यदि जावा सी (करता है) तो (5) {…} जैसे संख्यात्मक शर्तों की अनुमति क्यों नहीं देता है?


33

मेरे पास ये दो छोटे कार्यक्रम हैं:

सी

#include <stdio.h>
int main()
{
    if (5) {
        printf("true\n");
    }
    else {
        printf("false\n");
    }

    return 0;
}

जावा

class type_system {
   public static void main(String args[]) {
       if (5) {
           System.out.println("true");
       }
       else {
           System.out.println("false");
       }
   }
}

जो त्रुटि संदेश की रिपोर्ट करता है:

type_system.java:4: error: incompatible types: int cannot be converted to boolean
       if (5) {
           ^
1 error

मेरी समझ

अब तक, मैंने इस उदाहरण को विभिन्न प्रकार की प्रणालियों के प्रदर्शन के रूप में समझा। सी अधिक कमजोर रूप से टाइप किया गया है और त्रुटियों के बिना इंट से बूलियन में रूपांतरण की अनुमति देता है। जावा अधिक दृढ़ता से टाइप किया गया है और विफल रहता है, क्योंकि कोई भी अंतर्निहित बातचीत की अनुमति नहीं है।

इसलिए, मेरा सवाल: मैंने चीजों को कहां गलत समझा?

जिसे मैं नहीं ढूंढ रहा हूं

मेरा प्रश्न खराब कोडिंग शैली से संबंधित नहीं है। मुझे पता है कि यह बुरा है, लेकिन मुझे इसमें दिलचस्पी है कि C इसे अनुमति क्यों देता है और जावा नहीं। इसलिए, मुझे भाषा के प्रकार प्रणाली में दिलचस्पी है, विशेष रूप से इसकी मजबूती।


22
@ एंटोगी: जावा में उस प्रकार के सिस्टम के बारे में क्या है जिसे आप विशेष रूप से जानना चाहते हैं? टाइप सिस्टम इसे अनुमति नहीं देता है क्योंकि भाषा विनिर्देश इसे मना करता है। जिन कारणों से C इसे अनुमति देता है और जावा के पास दोनों भाषाओं में स्वीकार्य मानी जाने वाली चीज़ों के साथ सब कुछ नहीं है। टाइप सिस्टम का परिणामी व्यवहार इसका प्रभाव है, कारण नहीं।
रॉबर्ट हार्वे

8
@ एंटोगी: आपको क्यों लगता है कि आपने कुछ गलत समझा है? पाठ को फिर से पढ़ना, मुझे समझ नहीं आ रहा है कि आपका प्रश्न क्या है।
डॉक ब्राउन

26
वास्तव में, यह C. में कमजोर टाइपिंग का उदाहरण नहीं है। अतीत में (C89), C के पास बूलियन प्रकार भी नहीं था, इसलिए सभी "बूलियन" ऑपरेशन वास्तव में intमूल्यों पर संचालित होते थे । एक अधिक उचित उदाहरण होगा if (pointer)
रफ़लविंड

5
मैं नीचा दिखाती हूं क्योंकि ऐसा नहीं लगता है कि इसे समझने की कोशिश में बहुत शोध किया गया था।
jpmc26

11
ऐसा लगता है कि पूछा गया मूल प्रश्न संपादित संस्करण की तुलना में थोड़ा अलग है (यही कारण है कि कुछ टिप्पणियां और उत्तर एक अलग प्रश्न का उत्तर देते प्रतीत होते हैं)। अपने वर्तमान स्वरूप में, यहाँ एक प्रश्न नहीं लगता है। क्या गलतफहमी है? जावा बिल्कुल वैसा ही व्यवहार कर रहा है जैसा आपको लगता है कि यह होना चाहिए।
jamesdlin

जवाबों:


134

1. C और Java अलग-अलग भाषाएं हैं

यह तथ्य कि वे अलग तरह से व्यवहार करते हैं, बहुत आश्चर्यचकित नहीं होना चाहिए।

2. C से कोई रूपांतरण नहीं कर रहा intहैbool

यह कैसे हो सकता है? सी भी 1999 तकbool कन्वर्ट करने के लिए एक सही प्रकार नहीं था । सी 1970 के दशक में बनाया गया था, और ifइसका हिस्सा था इससे पहले कि यह भी सी था, वापस जब यह सिर्फ बी 1 में संशोधनों की एक श्रृंखला थी ।

ifNOPलगभग 30 वर्षों के लिए सी में बस नहीं था । इसने सीधे संख्यात्मक मूल्यों पर कार्य किया। C मानक ( PDF लिंक ) में क्रिया, boolS से C की शुरुआत के एक दशक बाद भी, अभी भी if(p 148) और ?:(p 100) के व्यवहार को "असमान 0 से" और "0 के बराबर" शब्दों का उपयोग करता है। "बूलियन शब्दों के बजाय" सच "या" झूठे "या कुछ समान।

आसानी से, ...

3. - नंबर सिर्फ वही होता है जो प्रोसेसर के निर्देशों पर काम करता है।

JZऔर JNZसशर्त शाखाओं के लिए आपके मूल x86 विधानसभा निर्देश हैं। संक्षिप्त विवरण " J ump if Z ero" और " J ump अगर N ot Z ero" हैं। PDP-11 के समतुल्य, जहाँ C की उत्पत्ति हुई है, BEQ(" B ranch if EQ ual") और BNE(" B ranch if N ot E qual")।

ये निर्देश जाँचते हैं कि पिछला ऑपरेशन शून्य हुआ था या नहीं और तदनुसार कूद (या नहीं)।

4. C ने कभी 2 की तुलना में सुरक्षा पर ज्यादा जोर दिया है

और, सुरक्षा को ध्यान में रखते हुए, उन्होंने फैसला किया कि एस को सीमित ifकरना booleanलागत के लायक था (दोनों इस तरह के प्रतिबंध को लागू करने और परिणामी लागत को कम करते हैं)।


1. B के पास बिल्कुल भी प्रकार नहीं है। असेंबली भाषा आम तौर पर या तो नहीं है। फिर भी B और असेंबली लैंग्वेज बस ब्रांचिंग को ठीक करने के लिए संभालती हैं।

2. डेनिस रिची के शब्दों में, B के लिए नियोजित संशोधनों का वर्णन करते समय जो C (जोर मेरा) बन गया था:

... ऐसा लगता था कि पात्रों और बाइट को संबोधित करने और आने वाले फ़्लोटिंग-पॉइंट हार्डवेयर की तैयारी के लिए एक टाइपिंग स्कीम आवश्यक थी। अन्य मुद्दे, विशेष रूप से सुरक्षा और इंटरफ़ेस जाँच, तब महत्वपूर्ण नहीं लगते थे , जब वे बाद में बने।


13
प्रोसेसर निर्देश के लिए सीधे सी मैपिंग में बूलियन अभिव्यक्तियों के बारे में अच्छा बिंदु। मैंने इसके बारे में पहले नहीं सोचा था।
रॉबर्ट हार्वे

17
मुझे लगता है कि बिंदु 4 भ्रामक है क्योंकि ऐसा लगता है कि सी को सुरक्षा के कुछ ध्यान केंद्रित हैं ... सी आपको मूल रूप से कुछ भी करने देगा जो आप चाहते हैं: सी आपको पता है कि आप क्या कर रहे हैं, अक्सर शानदार विनाशकारी परिणाम।
टेम्पोरलवॉल्फ

13
@TemporalWolf आप कहते हैं कि जैसे कि C आपको वह करने देता है जो आप चाहते हैं कि वह बुरा था। मेरी राय में अंतर यह है कि सी प्रोग्रामर के लिए लिखा गया था और एक बुनियादी क्षमता की उम्मीद है। जावा कोड बंदरों के लिए लिखा गया है और यदि आप टाइप कर सकते हैं तो आप इसमें प्रोग्राम कर सकते हैं। अक्सर शानदार बुरी तरह से लेकिन सही कौन परवाह करता है? मैं कभी नहीं भूलूंगा जब परिचयात्मक जावा वर्ग में एक शिक्षक को मेरे सीएस नाबालिग के एक हिस्से के रूप में लेने के लिए मजबूर किया गया था, ने बताया कि फिबोनासी संख्याओं की गणना करने के लिए पुनरावृत्ति का उपयोग करना उपयोगी हो सकता है क्योंकि यह "लिखना आसान" था। इसलिए हमारे पास जो सॉफ्टवेयर है, वह हमारे पास है।
DRF

25
@DRF एक C नेटवर्किंग क्लास के लिए मेरे प्रोफेसरों में से एक ने कहा "C हैंड ग्रेनेड के एक बॉक्स की तरह है जिसमें सभी पिन बाहर निकले हुए हैं।" आपको बहुत शक्ति मिल गई है, लेकिन यह अनिवार्य रूप से आपके चेहरे पर उड़ने की गारंटी है। अधिकांश मामलों में, यह परेशानी के लायक नहीं है, और आप उच्च-स्तरीय भाषा के साथ कहीं अधिक उत्पादक होंगे। क्या मैंने गति में वृद्धि के 6 क्रम प्राप्त करने के लिए पायथन को हैकी सी बिट-ट्विडलिंग में स्थानांतरित कर दिया है? हाँ, हाँ मेरे पास है। लेकिन वह अपवाद है, नियम नहीं। मैं पायथन में एक दिन में पूरा कर सकता हूं कि मुझे सी में दो सप्ताह क्या लगेगा ... और मैं एक सभ्य सी प्रोग्रामर हूं।
टेम्पोरलवॉल्फ

11
@DRF शीर्ष नाम कंपनियों द्वारा विकसित मुख्यधारा के सॉफ्टवेयर में बफर ओवरफ्लो के प्रचलन को देखते हुए, जाहिर तौर पर बुनियादी क्षमता वाले प्रोग्रामर पर भी भरोसा नहीं किया जा सकता है।
मोनिका

14

सी 2011 ऑनलाइन ड्राफ्ट

6.8.4.1 ifकथन

बाधा

1 कथन की नियंत्रण अभिव्यक्ति में ifस्केलर प्रकार होगा।

शब्दार्थ

2 2 दोनों रूपों में, पहला सबस्टेशन निष्पादित किया जाता है यदि अभिव्यक्ति असमान से 0. की तुलना करती elseहै, तो फॉर्म में, दूसरा सबस्टेशन को निष्पादित किया जाता है यदि अभिव्यक्ति 0. के बराबर है। यदि पहला सबस्टेशन एक लेबल के माध्यम से पहुंचता है, तो दूसरा सबस्टेशन होता है। निष्पादित नहीं किया गया।

3 elseयदि वाक्यविन्यास द्वारा अनुमति दी जाती है तो लेक्सिक रूप से निकटतम पूर्ववर्ती के साथ जुड़ा हुआ है।

ध्यान दें कि यह खंड केवल यह निर्दिष्ट करता है कि नियंत्रण अभिव्यक्ति में एक स्केलर प्रकार ( char/ short/ int/ long/ आदि) होगा, विशेष रूप से बूलियन प्रकार नहीं। यदि नियंत्रण अभिव्यक्ति में शून्य-शून्य मान है तो एक शाखा निष्पादित होती है।

इससे तुलना कीजिए

जावा एसई 8 भाषा विशिष्टता

14.9 ifस्टेटमेंट स्टेटमेंट

किसी ifस्टेटमेंट के सशर्त निष्पादन या दो स्टेटमेंट्स की सशर्त पसंद की अनुमति देता है, एक या दूसरे को निष्पादित करता है, लेकिन दोनों को नहीं।
    IfThenStatement :
        यदि ( अभिव्यक्ति ) कथन

    IfThenElseStatement :
        if ( एक्सप्रेशन ) StatementNoShortIf और स्टेटमेंट

    इफेनएल्सेस्टेमेंटन नोशॉर्टआईफ़ :
        if ( एक्सप्रेशन ) StatementNoShortIf और कथनNNShortIf
अभिव्यक्ति प्रकार होना आवश्यक है booleanया Boolean, या एक संकलन समय त्रुटि उत्पन्न होती है।

जावा, ओटीओएच, विशेष रूप से आवश्यकता है कि एक ifबयान में नियंत्रण अभिव्यक्ति का बूलियन प्रकार हो।

इसलिए, यह कमजोर बनाम मजबूत टाइपिंग के बारे में नहीं है, यह इस बारे में है कि प्रत्येक संबंधित भाषा परिभाषा एक वैध नियंत्रण अभिव्यक्ति के रूप में क्या निर्दिष्ट करती है।

संपादित करें

के रूप में क्यों भाषाओं इस विशेष सम्मान, कई बिंदुओं में अलग हैं:

  1. C, B से लिया गया था, जो एक "टाइपलेस" भाषा थी - मूल रूप से, सब कुछ एक 32- से 36-बिट शब्द (हार्डवेयर के आधार पर) था, और सभी अंकगणितीय ऑपरेशन पूर्णांक ऑपरेशन थे। सी के प्रकार प्रणाली को एक बार में थोड़ा सा बोल्ट किया गया था, जैसे कि ...

  2. सी भाषा के 1999 संस्करण तक एक अलग बुलियन प्रकार नहीं था। C ने प्रतिनिधित्व करने के लिए शून्य falseऔर गैर-शून्य का प्रतिनिधित्व करने के लिए बस B कन्वेंशन का अनुसरण किया true

  3. दशकों की एक अच्छी जोड़ी के द्वारा जावा पोस्ट-डेट सी, और विशेष रूप से सी और सी ++ की कुछ कमियों को दूर करने के लिए डिज़ाइन किया गया था। एक ifबयान में नियंत्रण अभिव्यक्ति क्या हो सकती है, इस पर प्रतिबंध को कसने में कोई संदेह नहीं था।

  4. किसी भी दो प्रोग्रामिंग भाषाओं से चीजों को उसी तरह करने की उम्मीद करने का कोई कारण नहीं है । यहां तक ​​कि सी और सी ++ के रूप में निकटता से संबंधित भाषाएं कुछ दिलचस्प तरीकों से विचलन करती हैं, जैसे कि आपके पास कानूनी सी प्रोग्राम हो सकते हैं जो कानूनी सी ++ प्रोग्राम नहीं हैं, या कानूनी सी ++ प्रोग्राम हैं, लेकिन विभिन्न शब्दार्थ के साथ, आदि।


बहुत दुख की बात है, मैं दो उत्तरों को "स्वीकृत" के रूप में चिह्नित नहीं कर सकता
हूं

1
हां, यह प्रश्न का अच्छा विवरण है। लेकिन सवाल ने पूछा कि दो भाषाओं के बीच यह अंतर क्यों है । आपने इसे बिल्कुल संबोधित नहीं किया है।
दाऊद का कहना है कि मोनिका

@DawoodibnKareem: सवाल यह था कि जावा intको रूपांतरण की अनुमति C से क्यों booleanनहीं मिली। इसका उत्तर यह है कि सी में ऐसा कोई रूपांतरण नहीं है। भाषाएँ अलग हैं क्योंकि वे अलग-अलग भाषाएँ हैं।
जॉन बोडे

हां, "यह कमजोर बनाम मजबूत टाइपिंग के बारे में नहीं है"। बस ऑटो-बॉक्सिंग और ऑटो-अनबॉक्सिंग को देखें। यदि सी उन थे, यह किसी भी स्केलर प्रकार की अनुमति नहीं दे सकता है।
डिडुप्लिकेटर

5

कई उत्तर एम्बेडेड असाइनमेंट अभिव्यक्ति को लक्षित करते हुए प्रतीत होते हैं जो सशर्त अभिव्यक्ति के भीतर हैं। (जबकि यह एक संभावित प्रकार का संभावित नुकसान है, यह इस मामले में जावा त्रुटि संदेश का स्रोत नहीं है।)

संभवतः यह इसलिए है क्योंकि ओपी ने वास्तविक त्रुटि संदेश प्रकाशित नहीं किया था, और, कार्यवाहक ^सीधे =असाइनमेंट ऑपरेटर को इंगित करता है ।

हालाँकि संकलक इस ओर इशारा कर रहा है =क्योंकि यह वह ऑपरेटर है जो उस भाव के अंतिम मान (और इसलिए अंतिम प्रकार) का उत्पादन करता है जिसे सशर्त देखता है।

यह निम्न प्रकार की त्रुटि के साथ गैर-बूलियन मान के परीक्षण के बारे में शिकायत कर रहा है:

त्रुटि: असंगत प्रकार: int को बूलियन में नहीं बदला जा सकता है

कभी-कभी सुविधाजनक होने पर परीक्षण पूर्णांक, एक संभावित नुकसान माना जाता है जिसे जावा डिजाइनर बचने के लिए चुनते हैं। आखिरकार, जावा में एक सच्चा बूलियन डेटा प्रकार है , जो C नहीं है (इसका कोई बूलियन प्रकार नहीं है)

यह n / n-null के माध्यम से C के परीक्षण बिंदुओं पर भी लागू होता है if (p) ...और if (!p) ..., जो जावा आवश्यक बूलियन प्राप्त करने के लिए स्पष्ट तुलना ऑपरेटर की आवश्यकता के बजाय इसी तरह की अनुमति नहीं देता है।


1
सी करता है एक बूलियन प्रकार है। लेकिन यह ifबयान की तुलना में नया है ।
MSalters

3
@MSalters C का बूल अभी भी कवर के नीचे एक पूर्णांक है, इसलिए आप कर सकते हैं bool b = ...; int v = 5 + b;। यह एक पूर्ण बूलियन प्रकार वाली भाषाओं के लिए अलग है जिसका उपयोग अंकगणित में नहीं किया जा सकता है।
जूल्स

C का बूलियन सिर्फ एक बहुत छोटा पूर्णांक है। "सच" और "झूठे" को आसानी से मैक्रोज़ या जो भी हो, के साथ परिभाषित किया जा सकता है।
Oskar Skog

4
@ जूल्स: आप सिर्फ इशारा कर रहे हैं कि सी में कमजोर टाइप-सेफ्टी है। सिर्फ इसलिए कि एक बूलियन प्रकार धर्मान्तरित एक पूर्णांक मान के लिए इसका मतलब यह नहीं है कि यह है एक पूर्णांक प्रकार। आपके तर्क से, पूर्णांक प्रकार फ्लोटिंग-पॉइंट प्रकार होंगे क्योंकि int v = 5; float f = 2.0 + v;सी। में कानूनी है
MSalters

1
@MSalters वास्तव _Boolमें मानक द्वारा परिभाषित मानक अहस्ताक्षरित प्रकारों में से एक है (देखें 6.2.5 / 6)।
रुस्लान

2

असंगत प्रकार: int को बूलियन में नहीं बदला जा सकता है

मुझे इसमें दिलचस्पी है कि C इसे अनुमति क्यों देता है और जावा नहीं। इसलिए, मुझे भाषा के प्रकार प्रणाली में दिलचस्पी है, विशेष रूप से इसकी मजबूती।

आपके प्रश्न के दो भाग हैं:

जावा में परिवर्तित क्यों नहीं होता intहै boolean?

यह जावा के लिए नीचे फोड़ा जा रहा है जितना संभव हो उतना स्पष्ट होने का इरादा है। यह बहुत स्थिर है, बहुत "अपने चेहरे में" इसके प्रकार प्रणाली के साथ। अन्य भाषाओं में स्वचालित रूप से टाइप की जाने वाली चीजें जावा में नहीं हैं। आपको भी लिखना है int a=(int)0.5। जानकारी खोने के floatलिए परिवर्तित intकरना; के रूप में परिवर्तित intकरने booleanऔर इस तरह त्रुटि-प्रवण होगा। इसके अलावा, उन्हें बहुत सारे संयोजन निर्दिष्ट करने होंगे। निश्चित रूप से, ये बातें स्पष्ट प्रतीत होती हैं, लेकिन वे सावधानी के साथ पीछे हटने का इरादा रखते हैं।

ओह, और अन्य भाषाओं की तुलना में, जावा अपने विनिर्देश में बहुत सटीक था , क्योंकि बायटेकोड केवल आंतरिक कार्यान्वयन विवरण नहीं था। उन्हें किसी भी और सभी इंटरैक्शन को निर्दिष्ट करना होगा, ठीक है। बहुत बड़ा उपक्रम।

के ifअलावा अन्य प्रकारों को स्वीकार क्यों नहीं करता है boolean?

ifअन्य प्रकार की अनुमति देने के लिए पूरी तरह से अच्छी तरह से परिभाषित किया जा सकता है boolean। इसकी एक परिभाषा हो सकती है जो कहती है कि निम्नलिखित समतुल्य हैं:

  • true
  • int != 0
  • String साथ में .length>0
  • कोई भी अन्य वस्तु संदर्भ जो गैर है null(और Booleanमूल्य के साथ नहीं false)।
  • या यहां तक ​​कि: कोई भी अन्य वस्तु संदर्भ जो गैर है- nullऔर जिसकी विधि Object.check_if(मेरे द्वारा इस अवसर के लिए आविष्कार की गई) वापस आती है true

उन्होंने नहीं किया; इसकी कोई वास्तविक आवश्यकता नहीं थी, और वे इसे यथासंभव मजबूत, स्थिर, पारदर्शी, आसानी से पढ़ना आदि चाहते थे। कोई निहित विशेषताएं नहीं। इसके अलावा, कार्यान्वयन बहुत जटिल होगा, मुझे यकीन है, सभी संभावित मामलों के लिए प्रत्येक मूल्य का परीक्षण करने के लिए, इसलिए प्रदर्शन ने केवल एक छोटा कारक खेला हो सकता है (जावा उस दिन के कंप्यूटरों पर स्लो किया जाता था; याद रखें पहले रिलीज के साथ कोई जेआईटी संकलक नहीं था, कम से कम उन कंप्यूटरों पर नहीं जिन्हें मैंने इस्तेमाल किया था)।

गहरा कारण

एक गहरा कारण यह तथ्य भी हो सकता है कि जावा के आदिम प्रकार हैं, इसलिए इसकी प्रकार प्रणाली वस्तुओं और आदिम के बीच फटी हुई है। हो सकता है, अगर वे उन लोगों से बचते, तो चीजें दूसरी तरह से बदल जातीं। पिछले अनुभाग में दिए गए नियमों के साथ, उन्हें प्रत्येक एकल आदिम की सत्यता को स्पष्ट रूप से परिभाषित करना होगा (क्योंकि आदिम एक सुपर क्लास साझा नहीं करते हैं, और nullआदिम के लिए अच्छी तरह से परिभाषित नहीं है )। यह एक दुःस्वप्न में बदल जाएगा, जल्दी से।

आउटलुक

खैर, और अंत में, शायद यह भाषा डिजाइनरों की एक प्राथमिकता है। प्रत्येक भाषा को अपने तरीके से स्पिन करने लगता है ...

उदाहरण के लिए, रूबी का कोई आदिम प्रकार नहीं है। सब कुछ, वस्तुतः सब कुछ, एक वस्तु है। उनके पास यह सुनिश्चित करने का बहुत आसान समय है कि प्रत्येक वस्तु की एक निश्चित विधि है।

रूबी सभी प्रकार की वस्तुओं पर सत्यता की तलाश करती है जिसे आप इसे फेंक सकते हैं। दिलचस्प रूप से पर्याप्त है, इसका अभी भी कोई booleanप्रकार नहीं है (क्योंकि इसमें कोई आदिम नहीं है), और इसका कोई Booleanवर्ग भी नहीं है। यदि आप पूछते हैं कि किस वर्ग का मूल्य true(हाथ से उपलब्ध है true.class), तो आपको मिलता है TrueClass। उस वर्ग के पास वास्तव में विधियाँ हैं, अर्थात् बूलियन्स के लिए 4 संचालक ( | & ^ ==)। यहाँ, ifइसके मान को गलत मानते हैं यदि और केवल ( falseया रूबी में से)। बाकी सब सच है। तो, या दोनों सच हैं।nilnull0""

यह उनके लिए एक ऐसा तरीका बनाने के लिए तुच्छ होगा Object#truthy?जो किसी भी वर्ग के लिए लागू किया जा सकता है और एक व्यक्तिगत सच्चाई लौटा सकता है। उदाहरण के लिए, String#truthy?गैर-रिक्त स्ट्रिंग्स या व्हाट्सएप के लिए सही होने के लिए लागू किया जा सकता था। हालांकि, ज्यादातर विभागों में रूबी जावा का विरोधी है (मिक्सिन के साथ गतिशील बतख-टाइपिंग, फिर से खोलने वाली कक्षाएं और वह सब)।

जो एक पर्ल प्रोग्रामर के लिए आश्चर्य की बात हो सकती है, जो $value <> 0 || length($value)>0 || defined($value)सच्चाई होने के लिए उपयोग किया जाता है । और इसी तरह।

एसक्यूएल को इस कन्वेंशन के साथ दर्ज करें कि nullकिसी भी अभिव्यक्ति के अंदर यह स्वचालित रूप से गलत है, चाहे जो भी हो। तो (null==null) = false। रूबी में, (nil==nil) = true। अच्छा समय।


वास्तव में, ((int)3) * ((float)2.5)जावा (यह है 7.5f) में काफी अच्छी तरह से परिभाषित किया गया है ।
पाओलो एबरमन

आप सही हैं, @ PaloEbermann, मैंने वह उदाहरण हटा दिया है।
AoE

वाह वहाँ ... टिप्पणी करने वालों से सराहना करेंगे और वास्तव में जवाब को नष्ट करने के लिए मतदान किया।
AoE

से वास्तव में रूपांतरण intकरने के लिए floatभी सामान्य रूप में जानकारी खो देता है। क्या जावा भी इस तरह के निहित कलाकारों को मना करता है?
रुस्लान

@ रोलन नं (लंबे समय तक (दोहरे) के लिए समान) - मुझे लगता है कि विचार यह है कि संभावित सूचना हानि केवल कम से कम महत्वपूर्ण स्थानों पर होती है, और केवल उन मामलों में होती है जिन्हें इतना महत्वपूर्ण नहीं माना जाता है (काफी बड़े पूर्णांक मान)।
पाओलो एबरमन

1

अन्य ठीक जवाबों के अलावा, मैं भाषाओं के बीच स्थिरता के बारे में बात करना चाहूंगा।

जब हम एक गणितीय रूप से शुद्ध विचार करते हैं, तो हम समझते हैं कि स्थिति सही या गलत हो सकती है, कोई अन्य मूल्य नहीं। हर प्रमुख प्रोग्रामिंग भाषा इस गणितीय आदर्श का सम्मान करती है; यदि आप एक बूलियन को सच / गलत मान देते हैं, तो आप हर समय सुसंगत, सहज व्यवहार देख सकते हैं।

अब तक सब ठीक है। यह वह है जो जावा लागू करता है, और केवल जावा लागू करता है।

अन्य भाषाएं गैर-बूलियन मूल्यों के लिए उपयुक्तता लाने की कोशिश करती हैं। उदाहरण के लिए:

  • मान लीजिए nकि एक पूर्णांक है। अब के if (n)लिए आशुलिपि परिभाषित करते हैं if (n != 0)
  • मान लीजिए xकि एक फ्लोटिंग-पॉइंट नंबर है। अब के if (x)लिए आशुलिपि परिभाषित करते हैं if (x != 0 && !isNaN(x))
  • मान लीजिए pकि एक सूचक प्रकार है। अब के if (p)लिए आशुलिपि परिभाषित करते हैं if (p != null)
  • मान लीजिए sकि एक स्ट्रिंग प्रकार है। अब परिभाषित if (s)करते हैं if (s != null && s != "")
  • मान लीजिए aकि एक सरणी प्रकार है। अब परिभाषित if (a)करते हैं if (a != null && a.length > 0)

शॉर्टहैंड प्रदान करने का यह विचार यदि परीक्षण सतह पर अच्छा लगता है ... जब तक आप डिजाइन और राय में अंतर नहीं करते हैं:

  • if (0)सी, पायथन, जावास्क्रिप्ट में झूठा माना जाता है; लेकिन रूबी में सच माना जाता है।
  • if ([]) अजगर में झूठा माना जाता है लेकिन जावास्क्रिप्ट में सच है।

प्रत्येक भाषा के भावों के एक तरीके या किसी अन्य के साथ व्यवहार करने के अपने अच्छे कारण हैं। (उदाहरण के लिए, रूबी में केवल मिथ्या मूल्य हैं falseऔर nilइसलिए 0सत्य है।)

जावा ने आपको एक स्पष्ट कथन के लिए एक बूलियन मूल्य की आपूर्ति करने के लिए मजबूर करने के लिए एक स्पष्ट डिजाइन अपनाया। यदि आपने C / Ruby / Python से Java में जल्दबाजी में कोड का अनुवाद किया है, तो आप किसी भी तरह के शिथिलता को नहीं छोड़ सकते हैं यदि परीक्षण अपरिवर्तित हैं; आपको जावा में स्पष्ट रूप से शर्त लिखनी होगी। एक पल रुक कर सोचने से आप बुरी गलतियों से बच सकते हैं।


1
क्या आप जानते हैं कि x != 0जैसा है वैसा ही है x != 0 && !isNaN(x)? इसके अलावा, यह सामान्य तौर s != nullपर पॉइंटर्स के लिए है, लेकिन नॉन-पॉइंटर्स के लिए कुछ और है।
Deduplicator

@ डेडप्लिकेटर किस भाषा में वही है?
पाओलो एबरमन

1
IEEE754, NaN Na 0. NaN Na का उपयोग करना। तो अगर (x) निष्पादित करेगा, और यदि (x) भी निष्पादित करेगा ...
gnasher729

0

खैर, सी, पॉइंटर, बूलियन (C99 के बाद से), नंबर (फ्लोटिंग-पॉइंट या नहीं) और एन्युमरेशन (संख्याओं की सीधी मैपिंग के कारण) में प्रत्येक स्केलर टाइप में "प्राकृतिक" फॉल्सी वैल्यू होती है, इसलिए यह किसी भी सशर्त अभिव्यक्ति के लिए पर्याप्त है। ।

जावा में वे भी हैं (भले ही जावा पॉइंटर्स को संदर्भ कहा जाता है और भारी प्रतिबंधित है), लेकिन इसने जावा 5.0 में ऑटो-बॉक्सिंग की शुरुआत की, जो अस्वीकार्य रूप से पानी को पिघला देता है। इसके अलावा, जावा-प्रोग्रामर टाइपिंग के आंतरिक मूल्य को अधिक दर्शाते हैं।

एक त्रुटि जो बहस को जन्म देती है कि क्या सशर्त अभिव्यक्तियों को बूलियन प्रकार तक सीमित करना एक असाइनमेंट लिखने का टाइपो है जहां एक तुलना का इरादा था, जो सशर्त अभिव्यक्तियों के प्रकार को सीमित करके संबोधित नहीं किया जाता है , लेकिन नग्न असाइनमेंट-अभिव्यक्ति के उपयोग को रोककर। इसके मूल्य के लिए।

किसी भी आधुनिक C या C ++ कंपाइलर को आसानी से हैंडल किया जाता है, यदि पूछे जाने पर ऐसे संदिग्ध कंस्ट्रक्शन के लिए चेतावनी या त्रुटि देता है।
उन मामलों के लिए जहां यह बिल्कुल वही था, जो कोष्ठक जोड़ने में मदद करता है।

संक्षेप में, बूलियन तक सीमित (और जावा में बॉक्सिंग समतुल्य) =असाइनमेंट संकलन-त्रुटियों के लिए चुनने के कारण टाइपोस की एक वर्ग बनाने की असफल कोशिश की तरह दिखता है ।


==बूलियन ऑपरेंड्स के साथ उपयोग करना , जिनमें से पहला एक वैरिएबल है (जो तब टाइपो द्वारा किया जा सकता है =) ifअन्य प्रकारों की तुलना में बहुत कम बार होता है, मैं कहूंगा, इसलिए यह केवल एक अर्ध-असफल प्रयास है।
पाओलो एबरमैन

0.0 -> गलत और 0.0 के अलावा कोई भी मान रखने वाला -> सच मुझे बिल्कुल भी "स्वाभाविक" नहीं लगता है।
gnasher729

@ Pa @loEbermann: दुर्भाग्यपूर्ण साइड-इफेक्ट्स के साथ आंशिक परिणाम, जबकि साइड-इफेक्ट्स के बिना लक्ष्य को प्राप्त करने का एक आसान तरीका है, मेरी पुस्तक में एक स्पष्ट विफलता है।
डिडुप्लिकेटर

आप अन्य कारणों को याद कर रहे हैं। क्या की truthy मूल्य के बारे में "", (Object) "", 0.0, -0.0, NaN, खाली सरणियों, और Boolean.FALSE? विशेष रूप से अंतिम एक मजाकिया है, क्योंकि यह नॉन-नेल पॉइंटर (सच्चा) है, जो झूठे को अनबॉक्स करता है। +++ मुझे लेखन से भी नफरत है if (o != null), लेकिन मुझे हर दिन कुछ चार्ट सहेजने और मुझे अपनी "चतुर" अभिव्यक्ति पर डेब्यू करने के लिए आधा दिन बिताने की अनुमति नहीं है। उस ने कहा, मैं जावा के लिए कुछ मध्य मार्ग देखना पसंद करूंगा: अधिक उदार नियम लेकिन कोई अस्पष्टता बिल्कुल नहीं छोड़ता।
माॅर्टिनस

@maaartinus: जैसा कि मैंने कहा, जावा 5.0 में ऑटो-अनबॉक्सिंग की शुरुआत का मतलब था कि यदि वे एक सत्य-मूल्य को इंगित करते हैं, जो कि नल-नेस से पॉइंटर्स के अनुरूप है, तो उन्हें काफी समस्या होगी। लेकिन यह ऑटो (-) बॉक्सिंग के साथ एक समस्या है, कुछ और नहीं। ऑटो के बिना एक भाषा- (संयुक्त राष्ट्र) सी की तरह मुक्केबाजी खुशी से मुक्त है।
डिडुप्लिकेटर

-1

मेरा प्रश्न खराब कोडिंग शैली से संबंधित नहीं है। मैं इसका बुरा जानता हूं, लेकिन मैं अंतर्मुखी हूं कि C इसे अनुमति क्यों देता है और जावा नहीं।

जावा के डिजाइन लक्ष्यों में से दो थे:

  1. डेवलपर को व्यावसायिक समस्या पर ध्यान केंद्रित करने की अनुमति दें। चीजों को सरल और कम त्रुटि वाली बनायें, जैसे कचरा संग्रहण ताकि डेवलपर्स को स्मृति लीक पर ध्यान केंद्रित करने की आवश्यकता न हो।

  2. प्लेटफार्मों के बीच पोर्टेबल , उदाहरण के लिए किसी भी कंप्यूटर पर किसी भी सीपीयू के साथ चलाएं।

एक अभिव्यक्ति के रूप में असाइनमेंट का उपयोग टाइपोस के कारण बहुत सारे कीड़े पैदा करने के लिए जाना जाता था, इसलिए लक्ष्य # 1 से ऊपर, इसे उस तरह से अनुमति नहीं दी जाती है जिस तरह से आप इसका उपयोग करने की कोशिश कर रहे हैं।

इसके अलावा, यह उल्लेख करते हुए कि कोई भी नॉनजरो मूल्य = सही और कोई शून्य मान = गलत आवश्यक रूप से पोर्टेबल नहीं है (हाँ, यह विश्वास है या नहीं, कुछ सिस्टम 0 को सच मानते हैं और 1 झूठे के रूप में ), इसलिए लक्ष्य # 2 से ऊपर, को स्पष्ट रूप से अनुमति नहीं है। । आप अभी भी स्पष्ट रूप से कास्ट कर सकते हैं।


4
जब तक इसे जावा 8 में नहीं जोड़ा गया है, तब तक संख्यात्मक प्रकार और बूलियन के बीच कोई स्पष्ट डाली नहीं है। एक बूलियन को एक संख्यात्मक मान परिवर्तित करने के लिए आपको एक तुलना ऑपरेटर का उपयोग करना होगा; एक बूलियन मान को एक संख्यात्मक में परिवर्तित करने के लिए जिसे आप आमतौर पर टर्नरी ऑपरेटर का उपयोग करते हैं।
पीटर टेलर

आप उन टाइपोस के कारण इसके मूल्य के लिए असाइनमेंट के उपयोग को रोकने के लिए एक मामला बना सकते हैं। लेकिन यह देखते हुए कि आप जावा में कितनी बार == सही और == गलत देखते हैं, जाहिर है कि कंट्रोलिंग एक्सप्रेशन को (वैकल्पिक रूप से बॉक्सिंग) बूलियन प्रकार तक सीमित करने में मदद नहीं मिलती है।
डेडुप्लिकेटर

जावा तुच्छता से सुनिश्चित करेगा कि "कुछ सिस्टम 0 को सच मानें और 1 को झूठा", क्योंकि यह जावा का शून्य और जावा का झूठा है। यह वास्तव में कोई फर्क नहीं पड़ता कि ओएस इसके बारे में क्या सोचता है।
महाआरती

-1

एक उदाहरण के रूप में अन्य भाषाएं क्या करती हैं: स्विफ्ट को "बूलियन टाइप" प्रोटोकॉल का समर्थन करने वाले एक प्रकार की अभिव्यक्ति की आवश्यकता होती है, जिसका अर्थ है कि इसमें "बूलवैल्यू" विधि होनी चाहिए। "बूल" प्रकार स्पष्ट रूप से इस प्रोटोकॉल का समर्थन करता है और आप अपने स्वयं के प्रकार का समर्थन कर सकते हैं। पूर्णांक प्रकार इस प्रोटोकॉल का समर्थन नहीं करते हैं।

भाषा के पुराने संस्करणों में वैकल्पिक प्रकारों ने "बूलियन टाइप" का समर्थन किया ताकि आप "अगर x! = Nil" के बजाय "if x" लिख सकें। जो एक "वैकल्पिक बूल" का उपयोग करके बहुत भ्रमित करता है। एक वैकल्पिक बूल में मान शून्य, गलत या सत्य होता है और यदि "b" सही नहीं होता है और यदि b सत्य या गलत है तो b को निष्पादित किया जाता है। यह अब अनुमति नहीं है।

और वहाँ एक लड़का है जो असली नापसंद अपने क्षितिज खोलने लगता है ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.