X == (x = y) समान क्यों नहीं है (x = y) == x?


207

निम्नलिखित उदाहरण पर विचार करें:

class Quirky {
    public static void main(String[] args) {
        int x = 1;
        int y = 3;

        System.out.println(x == (x = y)); // false
        x = 1; // reset
        System.out.println((x = y) == x); // true
     }
}

मुझे यकीन नहीं है कि अगर जावा लैंग्वेज स्पेसिफिकेशन में कोई आइटम है जो किसी चर के पिछले मूल्य को दाईं ओर ( x = y) के साथ तुलना करने के लिए लोड करता है , जो कि ब्रैकेट्स द्वारा निहित आदेश द्वारा पहले गणना की जानी चाहिए।

पहली अभिव्यक्ति का मूल्यांकन क्यों होता है false, लेकिन दूसरा मूल्यांकन trueकैसे करता है ? मैंने (x = y)पहले मूल्यांकन किए जाने की उम्मीद की होगी, और फिर यह xखुद ( 3) और फिर से तुलना करेगा true


यह सवाल एक जावा एक्सप्रेशन में सबएक्सप्रेस के मूल्यांकन के क्रम से अलग है , जो xनिश्चित रूप से यहां 'सबप्रेशन' नहीं है। इसे 'मूल्यांकन' के बजाय तुलना के लिए लोड करने की आवश्यकता है । सवाल यह है कि जावा-विशिष्ट और अभिव्यक्ति x == (x = y), दूर-दराज के अव्यवहारिक निर्माणों के विपरीत, जो आमतौर पर मुश्किल साक्षात्कार प्रश्नों के लिए तैयार किए गए थे, एक वास्तविक परियोजना से आए थे। यह तुलना-और-मुहावरे के लिए एक-पंक्ति प्रतिस्थापन माना जाता था

int oldX = x;
x = y;
return oldX == y;

जो, x86 CMPXCHG अनुदेश से भी सरल होने के कारण, जावा में एक छोटी अभिव्यक्ति के योग्य था।


62
बाएं हाथ की ओर का मूल्यांकन हमेशा दाहिने हाथ की तरफ से पहले किया जाता है। कोष्ठक से कोई फर्क नहीं पड़ता।
लुई वासरमैन

11
अभिव्यक्ति x = yका मूल्यांकन निश्चित रूप से प्रासंगिक है, और उस साइड इफेक्ट का कारण बनता xहै जिसका मूल्य निर्धारित किया गया है y
लुई वासरमैन

50
अपने आप को और अपने साथियों को एक एहसान करो और राज्य परीक्षा के रूप में एक ही पंक्ति में राज्य उत्परिवर्तन को न मिलाएं। ऐसा करने से आपके कोड की पठनीयता कम हो जाती है। (कुछ मामले ऐसे हैं जहां यह परमाणु आवश्यकताओं के कारण बिल्कुल आवश्यक है, लेकिन उन लोगों के लिए कार्य पहले से मौजूद हैं और उनके उद्देश्य को तुरंत पहचान लिया जाएगा।)
jpmc26

50
असली सवाल यह है कि आप इस तरह से कोड क्यों लिखना चाहते हैं।
klutt

26
आपके प्रश्न की कुंजी आपके झूठे विश्वास है कि कोष्ठक मूल्यांकन क्रम को प्रभावित करता है। यह एक आम धारणा है कि हमें प्राथमिक विद्यालय में गणित कैसे पढ़ाया जाता है और क्योंकि कुछ शुरुआती प्रोग्रामिंग किताबें अभी भी गलत हैं , लेकिन यह एक गलत धारणा है। यह एक बहुत लगातार सवाल है। विषय पर मेरे लेख पढ़ने से आपको लाभ हो सकता है; वे C # के बारे में हैं, लेकिन वे जावा पर लागू होते हैं: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
एरिक

जवाबों:


97

जो, कोष्ठक द्वारा निहित आदेश द्वारा, पहले गणना की जानी चाहिए

नहीं। यह एक आम गलत धारणा है कि गणना या मूल्यांकन क्रम पर कोष्ठक का कोई (सामान्य) प्रभाव पड़ता है। वे केवल आपकी अभिव्यक्ति के हिस्सों को एक विशेष पेड़ में ले जाते हैं, जो सही ऑपरेंड को काम के लिए सही संचालन के लिए बाध्य करते हैं।

(और, यदि आप उनका उपयोग नहीं करते हैं, तो यह जानकारी "पूर्वता" और ऑपरेटरों की संबद्धता से आती है, कुछ ऐसा है जो भाषा के वाक्यविन्यास के पेड़ को परिभाषित करने का एक परिणाम है। वास्तव में, यह तब भी ठीक है जब आप काम करते हैं। कोष्ठक का उपयोग करें, लेकिन हम सरल करते हैं और कहते हैं कि हम किसी भी पूर्ववर्ती नियमों पर भरोसा नहीं कर रहे हैं।)

एक बार ऐसा हो जाने के बाद (अर्थात जब आपका कोड एक प्रोग्राम में पार्स हो गया होता है) तब भी उन ऑपरेंड्स का मूल्यांकन करने की आवश्यकता होती है, और इसके बारे में अलग-अलग नियम हैं कि यह कैसे किया जाता है: नियमों (जैसा कि एंड्रयू ने हमें दिखाया है) बताते हैं कि प्रत्येक ऑपरेशन का एलएचएस जावा में पहले मूल्यांकन किया जाता है।

ध्यान दें कि सभी भाषाओं में ऐसा नहीं है; उदाहरण के लिए, C ++ में, जब तक कि आप शॉर्ट-सर्कुलेटिंग ऑपरेटर का उपयोग नहीं करते हैं , जैसे &&या ||, ऑपरेंड्स का मूल्यांकन क्रम आमतौर पर अनिर्दिष्ट होता है और आपको इस पर किसी भी तरह भरोसा नहीं करना चाहिए।

शिक्षकों को भ्रामक वाक्यांशों का उपयोग करते हुए ऑपरेटर की पूर्ववर्ती व्याख्या को रोकने की आवश्यकता है जैसे "यह पहले जोड़ देता है"। एक अभिव्यक्ति को देखते हुए x * y + zउचित स्पष्टीकरण होगा "ऑपरेटर पूर्वता इसके अलावा बीच हो बनाता है x * yऔर zनहीं बल्कि बीच की तुलना में, yऔर zकिसी भी" आदेश "के उल्लेख के बिना,"।


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

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

5
@ जॉन: यह खराब हो जाता है। क्या 5 * 4 का मतलब 5 + 5 + 5 + 5 या 4 + 4 + 4 + 4 + 4 है? कुछ शिक्षक इस बात पर ज़ोर देते हैं कि उन विकल्पों में से केवल एक ही सही है।
ब्रायन

3
@Brian लेकिन ... लेकिन ... वास्तविक संख्याओं का गुणा सराहनीय है!
ऑर्बिट में लाइटनेस दौड़

2
मेरी सोच की दुनिया में, कोष्ठक की एक जोड़ी "के लिए आवश्यक है" का प्रतिनिधित्व करती है। Atinga * (b + c) * की गणना करते हुए, कोष्ठक यह व्यक्त करते हैं कि जोड़ का परिणाम गुणन के लिए आवश्यक है। एलएचएस-प्रथम या आरएचएस-प्रथम नियमों को छोड़कर , किसी भी अंतर्निहित ऑपरेटर वरीयताओं को पार्न्स द्वारा व्यक्त किया जा सकता है। (क्या यह सच है?) @Brian गणित में कुछ दुर्लभ मामले हैं जहाँ गुणा को बार-बार जोड़कर प्रतिस्थापित किया जा सकता है लेकिन यह हमेशा दूर का सच है (जटिल संख्याओं के साथ शुरू होता है लेकिन सीमित नहीं है)। अपने शिक्षकों चाहिए तो वास्तव में क्या कह रहे हैं लोगों पर नजर .... है
syck

164

==एक द्विआधारी समानता ऑपरेटर है

बाइनरी ऑपरेटर के बाएं हाथ के ऑपरेंड का मूल्यांकन पूरी तरह से किया जाता है , राइट-हैंड ऑपरेंड के किसी भी भाग का मूल्यांकन करने से पहले

जावा 11 विशिष्टता> मूल्यांकन आदेश> पहले बाएं हाथ के संचालन का मूल्यांकन करें


42
शब्द "प्रतीत होता है" लगता है जैसे वे निश्चित नहीं हैं, tbh।
श्री लिस्टर

86
"प्रतीत होता है" का अर्थ है कि विनिर्देश की आवश्यकता नहीं है कि संचालन वास्तव में उस क्रम में कालानुक्रम में किए जाते हैं, लेकिन इसके लिए आवश्यक है कि आप वही परिणाम प्राप्त करें जो आपको मिलेंगे।
रोबिन

24
@MrLister "प्रतीत होता है" उनके हिस्से पर एक खराब शब्द विकल्प प्रतीत होता है। "प्रकट" से उनका मतलब है "डेवलपर के लिए एक घटना के रूप में प्रकट"। "प्रभावी रूप से" एक बेहतर वाक्यांश हो सकता है।
केल्विन

18
C ++ समुदाय में यह "as-if" नियम के बराबर है ... ऑपरेंड को व्यवहार करने की आवश्यकता है "जैसे कि" इसे निम्नलिखित नियमों के अनुसार लागू किया गया था, भले ही तकनीकी रूप से ऐसा न हो।
माइकल ईडनफील्ड

2
@ केल्विन मैं सहमत हूं, मैंने "प्रतीत होता है" के बजाय उस शब्द को चुना होगा।
एमसी सम्राट

149

जैसा कि लुइसवासरमन ने कहा, अभिव्यक्ति का मूल्यांकन दाएं से बाएं किया जाता है। और जावा परवाह नहीं करता है कि वास्तव में "मूल्यांकन" क्या करता है, यह केवल (गैर वाष्पशील, अंतिम) मूल्य के साथ काम करने की परवाह करता है।

//the example values
x = 1;
y = 3;

तो पहले उत्पादन की गणना करने के लिए System.out.println(), निम्नलिखित किया जाता है:

x == (x = y)
1 == (x = y)
1 == (x = 3) //assign 3 to x, returns 3
1 == 3
false

और दूसरे की गणना करने के लिए:

(x = y) == x
(x = 3) == x //assign 3 to x, returns 3
3 == x
3 == 3
true

ध्यान दें कि दूसरा मान हमेशा सत्य का मूल्यांकन करेगा, भले ही इसके प्रारंभिक मूल्यों की परवाह किए बिना xऔर y, क्योंकि आप प्रभावी रूप से उस चर के लिए एक मान के असाइनमेंट की तुलना कर रहे हैं, और उस क्रम में मूल्यांकन किया जाएगा, a = bऔर bहमेशा उसी के अनुरूप होना चाहिए परिभाषा से।


"बाएं से दाएं" भी गणित में सही है, वैसे, जब आप एक कोष्ठक या पूर्वता प्राप्त करते हैं, तो आप उनके अंदर पुनरावृति करते हैं और मुख्य स्तरीय पर आगे बढ़ने से पहले बाएं से दाएं के अंदर सब कुछ बाहर निकालते हैं। लेकिन गणित कभी ऐसा नहीं करेगा; भेद केवल इसलिए मायने रखता है क्योंकि यह एक समीकरण नहीं है, बल्कि एक कॉम्बो ऑपरेशन है, जो एक कार्य और एक समीकरण दोनों में एक ही कार्य करता है । मैं ऐसा कभी नहीं करूंगा क्योंकि पठनीयता खराब है, जब तक मैं कोड गोल्फ नहीं कर रहा था या प्रदर्शन को अनुकूलित करने का कोई रास्ता नहीं तलाश रहा था, और फिर, वहाँ टिप्पणियाँ होंगी।
हार्पर - मोनिका

25

मुझे यकीन नहीं है कि जावा भाषा विनिर्देश में एक आइटम है जो एक चर के पिछले मूल्य को लोड करने का आदेश देता है ...

वहाँ है। अगली बार जब आप स्पष्ट न हों कि विनिर्देश क्या कहता है, कृपया विनिर्देश पढ़ें और फिर प्रश्न पूछें कि क्या यह अस्पष्ट है।

... सही पक्ष (x = y)जो, कोष्ठक द्वारा निहित आदेश द्वारा, पहले गणना की जानी चाहिए।

वह कथन झूठा है। कोष्ठक मूल्यांकन का एक आदेश नहीं देते हैं । जावा में, कोष्ठकों की परवाह किए बिना, मूल्यांकन का क्रम दाईं ओर छोड़ दिया जाता है। कोष्ठक निर्धारित करते हैं कि उपसंचाई सीमाएं कहां हैं, मूल्यांकन का क्रम नहीं।

पहली अभिव्यक्ति झूठ का मूल्यांकन क्यों करती है, लेकिन दूसरा सच का मूल्यांकन करता है?

==ऑपरेटर के लिए नियम यह है: मान का उत्पादन करने के लिए बाईं ओर का मूल्यांकन करें, मान का उत्पादन करने के लिए दाईं ओर का मूल्यांकन करें, मूल्यों की तुलना करें, तुलना अभिव्यक्ति का मूल्य है।

दूसरे शब्दों में, इसका अर्थ expr1 == expr2हमेशा वही होता है, जैसा आपने लिखा था temp1 = expr1; temp2 = expr2;और फिर मूल्यांकन किया था temp1 == temp2

=बाईं ओर एक स्थानीय चर के साथ ऑपरेटर के लिए नियम है: एक चर का उत्पादन करने के लिए बाईं ओर का मूल्यांकन करें, एक मूल्य का उत्पादन करने के लिए दाईं ओर का मूल्यांकन करें, असाइनमेंट निष्पादित करें, परिणाम वह मान है जो असाइन किया गया था।

इसलिए इसे एक साथ रखें:

x == (x = y)

हमारे पास एक तुलना ऑपरेटर है। मान उत्पन्न करने के लिए बाईं ओर का मूल्यांकन करें - हमें वर्तमान मूल्य मिलता है x। दाईं ओर मूल्यांकन करें: यह एक असाइनमेंट है इसलिए हम एक चर का उत्पादन करने के लिए बाईं ओर का मूल्यांकन करते हैं - चर x- हम सही पक्ष का मूल्यांकन करते हैं - वर्तमान मूल्य y- इसे असाइन करें xऔर परिणाम असाइन किया गया मान है। हम तब xअसाइन किए गए मान के मूल मान की तुलना करते हैं ।

आप (x = y) == xव्यायाम के रूप में कर सकते हैं । फिर, याद रखें, बाईं ओर के मूल्यांकन के सभी नियम दाईं ओर के मूल्यांकन के सभी नियमों से पहले होते हैं

मैंने अपेक्षा की होगी कि (x = y) पहले मूल्यांकन किया जाए, और फिर यह x की तुलना अपने आप से (3) करेगा और सही लौटेगा।

आपकी अपेक्षा जावा के नियमों के बारे में गलत मान्यताओं के एक सेट पर आधारित है। उम्मीद है कि अब आपके पास सही विश्वास है और भविष्य में सही चीजों की उम्मीद करेंगे।

यह प्रश्न "जावा एक्सप्रेशन में उपप्रकारों के मूल्यांकन के क्रम" से अलग है

यह कथन झूठा है। यह सवाल पूरी तरह से जर्मन है।

एक्स निश्चित रूप से यहां 'सबप्रेप्शन' नहीं है।

यह कथन भी असत्य है। यह प्रत्येक उदाहरण में दो बार एक उपसर्ग है ।

इसे 'मूल्यांकन' के बजाय तुलना के लिए लोड करने की आवश्यकता है।

मुझे इसका मतलब नहीं मालूम है।

स्पष्ट रूप से आपके पास अभी भी कई गलत विश्वास हैं। मेरी सलाह है कि आप विनिर्देश पढ़ें जब तक कि आपके झूठे विश्वासों को सच्चे विश्वासों द्वारा प्रतिस्थापित नहीं किया जाता है।

प्रश्न जावा-विशिष्ट है और एक्सप्रेशन इंटरव्यू के प्रश्नों के लिए आमतौर पर तैयार किए गए अव्यवहारिक निर्माणों के विपरीत एक्स == (एक्स = वाई), एक वास्तविक परियोजना से आया है।

अभिव्यक्ति की सिद्धता सवाल के लिए प्रासंगिक नहीं है। इस तरह के भावों के नियम विनिर्देश में स्पष्ट रूप से वर्णित हैं; इसे पढ़ें!

यह तुलना-और-मुहावरे के लिए एक-पंक्ति प्रतिस्थापन माना जाता था

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

संयोग से, C # ने एक लाइब्रेरी पद्धति के रूप में तुलना और प्रतिस्थापित किया है, जिसे मशीन अनुदेश के साथ जोड़ा जा सकता है। मेरा मानना ​​है कि जावा में ऐसी कोई विधि नहीं है, क्योंकि यह जावा प्रकार प्रणाली में प्रतिनिधित्व नहीं कर सकता है।


8
यदि कोई पूरे JLS से गुजर सकता है, तो जावा पुस्तकों को प्रकाशित करने का कोई कारण नहीं होगा और इस साइट का कम से कम आधा भी बेकार हो जाएगा।
जॉन मैक्लेन ने

8
@ जॉनमोक्लेन: मैं आपको विश्वास दिलाता हूं, पूरे विनिर्देश के माध्यम से जाने में कोई कठिनाई नहीं है, लेकिन यह भी, आप नहीं चाहते हैं। जावा विनिर्देशन एक उपयोगी "सामग्री की तालिका" से शुरू होता है जो आपको उन हिस्सों को जल्दी से प्राप्त करने में मदद करेगा जिन्हें आप सबसे अधिक रुचि रखते हैं। यह ऑनलाइन और कीवर्ड खोज योग्य भी है। उस ने कहा, आप सही हैं: बहुत सारे अच्छे संसाधन हैं जो आपको यह जानने में मदद करेंगे कि जावा कैसे काम करता है; आपको मेरी सलाह है कि आप उनका उपयोग करें!
एरिक लिपर्ट

8
यह उत्तर अनावश्यक रूप से कृपालु और अशिष्ट है। याद रखें: अच्छा हो
Walen

7
@LuisG: कोई कृपालु इरादा या निहित नहीं है; हम सभी एक-दूसरे से सीखने के लिए यहां हैं, और मैं कुछ भी करने की सिफारिश नहीं कर रहा हूं जब मैंने शुरुआत की थी तब मैंने खुद को नहीं किया था। और न ही यह असभ्य है। स्पष्ट रूप से और स्पष्ट रूप से उनकी झूठी मान्यताओं की पहचान करना मूल पोस्टर के लिए एक दयालुता है । "विनम्रता" के पीछे छिपना और लोगों को झूठी मान्यताओं को जारी रखने की अनुमति देना अस्वाभाविक है , और विचार की बुरी आदतों को पुष्ट करता है
एरिक लिपर्ट

5
@LuisG: मैं जावास्क्रिप्ट के डिजाइन के बारे में एक ब्लॉग लिखता था, और मुझे जो भी मददगार टिप्पणियां मिलीं, वे ब्रेंडन की ओर से स्पष्ट और स्पष्ट रूप से इंगित करती थीं, जहां मुझे यह गलत लगा। यह बहुत अच्छा था और मैंने उसे समय देने की सराहना की, क्योंकि मैंने अपने जीवन के अगले 20 साल अपने काम में उस गलती को नहीं दोहराए, या इससे भी बदतर, दूसरों को सिखाते हुए जीए। इसने मुझे दूसरों की उन्हीं झूठी मान्यताओं को सही करने का मौका दिया, जिसका इस्तेमाल खुद लोगों ने किया कि कैसे लोग झूठी बातों पर विश्वास करते हैं।
एरिक लिपर्ट

16

यह ऑपरेटर पूर्वता से संबंधित है और ऑपरेटरों का मूल्यांकन कैसे किया जा रहा है।

कोष्ठक '()' में उच्चता है और समतावाद बाएं से दाएं है। समानता '==' इस प्रश्न में आगे आती है और इसमें समतावाद बाएं से दाएं होता है। असाइनमेंट '=' अंतिम आता है और इसमें बाएं से दाएं जुड़ाव होता है।

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

अब मूल प्रश्न पर आता है:

int x = 1;
int y = 3;
System.out.println(x == (x = y)); // false

पहले x (1) को ढेर करने के लिए धकेल दिया जाएगा। तब आंतरिक (x = y) का मूल्यांकन किया जाएगा और मूल्य x (3) के साथ स्टैक करने के लिए धकेल दिया जाएगा। अब x (1) की तुलना x (3) से की जाएगी ताकि परिणाम गलत हो।

x = 1; // reset
System.out.println((x = y) == x); // true

यहां, (x = y) का मूल्यांकन किया जाएगा, अब x मान 3 हो जाएगा और x (3) को स्टैक पर धकेल दिया जाएगा। अब x (3) बदले हुए मूल्य के साथ समानता को ढेर करने के लिए धक्का दिया जाएगा। अब अभिव्यक्ति का मूल्यांकन किया जाएगा और दोनों समान होंगे इसलिए परिणाम सत्य है।


12

ये एक जैसे नहीं हैं। बाएं हाथ की ओर का मूल्यांकन हमेशा दाहिने हाथ की तरफ से पहले किया जाएगा, और कोष्ठक निष्पादन के आदेश को निर्दिष्ट नहीं करते हैं, लेकिन आदेशों का एक समूह।

साथ में:

      x == (x = y)

आप मूल रूप से वैसा ही कर रहे हैं:

      x == y

और x की तुलना के बाद y का मान होगा ।

इसके साथ:

      (x = y) == x

आप मूल रूप से वैसा ही कर रहे हैं:

      x == x

X के बाद y का मान लिया गया । और यह हमेशा सच लौटेगा ।


9

पहले परीक्षण में आप जाँच कर रहे हैं 1 == 3।

दूसरे परीक्षण में आपकी जाँच 3 == 3 करती है।

(x = y) मान प्रदान करता है और उस मान का परीक्षण किया जाता है। पूर्व उदाहरण में x = 1 पहले तो x सौंपा गया है। क्या 1 == 3 है?

उत्तरार्द्ध में, x को 3 असाइन किया गया है, और जाहिर है यह अभी भी 3. 3 == 3 है?


8

इस पर विचार करें, शायद सरल उदाहरण:

int x = 1;
System.out.println(x == ++x); // false
x = 1; // reset
System.out.println(++x == x); // true

इधर, पूर्व वेतन वृद्धि ऑपरेटर ++xलागू किया जाना चाहिए इससे पहले कि तुलना किया जाता है - जैसे (x = y)अपने उदाहरण में गणना की जानी चाहिए से पहले तुलना।

हालाँकि, अभिव्यक्ति का मूल्यांकन अभी भी बाएं से → सही से होता है , इसलिए पहली तुलना वास्तव में है 1 == 2जबकि दूसरी है 2 == 2
आपके उदाहरण में भी यही बात होती है।


8

अभिव्यक्तियों का मूल्यांकन बाएं से दाएं किया जाता है। इस मामले में:

int x = 1;
int y = 3;

x == (x = y)) // false
x ==    t

- left x = 1
- let t = (x = y) => x = 3
- x == (x = y)
  x == t
  1 == 3 //false

(x = y) == x); // true
   t    == x

- left (x = y) => x = 3
           t    =      3 
-  (x = y) == x
-     t    == x
-     3    == 3 //true

5

मूल रूप से पहला कथन x का मान 1 था इसलिए जावा 1 == की तुलना नए x चर से करता है जो समान नहीं होगा

दूसरे में आपने कहा x = y जिसका अर्थ है कि x का मान बदल गया है और इसलिए जब आप इसे फिर से कॉल करते हैं तो यह समान मूल्य होगा इसलिए यह सही है और x == x


4

== एक तुलना समानता ऑपरेटर है और यह बाएं से दाएं काम करता है।

x == (x = y);

यहाँ x के पुराने असाइन किए गए मान की तुलना x के नए असाइन मूल्य, (1 == 3) // असत्य से की गई है

(x = y) == x;

जबकि, यहाँ x के नए असाइन मूल्य की तुलना करने से ठीक पहले सौंपे गए एक्स के नए होल्डिंग मूल्य के साथ तुलना की जाती है, (3 ==)) सही

अब इस पर विचार करें

    System.out.println((8 + (5 * 6)) * 9);
    System.out.println(8 + (5 * 6) * 9);
    System.out.println((8 + 5) * 6 * 9);
    System.out.println((8 + (5) * 6) * 9);
    System.out.println(8 + 5 * 6 * 9);

आउटपुट:

342

278

702

342

278

इस प्रकार, कोष्ठक केवल तुलनात्मक अभिव्यक्तियों में नहीं, अंकगणितीय अभिव्यक्तियों में अपनी प्रमुख भूमिका निभाता है।


1
निष्कर्ष गलत है। अंकगणित और तुलना ऑपरेटरों के बीच व्यवहार अलग नहीं है। x + (x = y)और (x = y) + xतुलना ऑपरेटरों के साथ मूल के समान व्यवहार दिखाएगा।
JJJ

1
@JJJ x + (x = y) और (x = y) + x में कोई तुलना शामिल नहीं है, यह सिर्फ x को y मान प्रदान कर रहा है और इसे x में जोड़ रहा है।
निसरीन ढोंडिया

1
... हाँ, यह बात है। "लघुगणक अंकगणितीय भावों में अपनी प्रमुख भूमिका निभाता है केवल तुलनात्मक अभिव्यक्तियों में नहीं" गलत है क्योंकि अंकगणितीय और तुलनात्मक अभिव्यक्तियों में कोई अंतर नहीं है।
JJJ

2

यहाँ बात arithmatic ऑपरेटरों / दो ऑपरेटरों के बाहर संबंधपरक ऑपरेटर प्रधानता आदेश है =बनाम ==प्रमुख से एक है ==(संबंधपरक ऑपरेटर हावी) के रूप में इससे पहले आने =असाइनमेंट ऑपरेटरों। पूर्वता के बावजूद, मूल्यांकन का क्रम LTR है (LEFT TO RIGHT) पूर्वता मूल्यांकन आदेश के बाद तस्वीर में आता है। इसलिए, किसी भी बाधाओं के मूल्यांकन के बावजूद LTR है।


1
उत्तर गलत है। ऑपरेटर पूर्वता मूल्यांकन आदेश को प्रभावित नहीं करता है। स्पष्टीकरण के लिए शीर्ष मतदान के कुछ जवाब पढ़ें, विशेष रूप से यह एक
JJJ

1
सही, इसका वास्तव में जिस तरह से हमें सिखाया जाता है कि पूर्वधारणा पर प्रतिबंधों का भ्रम उन सभी चीजों के लिए आता है, लेकिन सही ढंग से कहा गया है कि इसका कोई प्रभाव नहीं है मूल्यांकन का क्रम बाएं से दाएं रहता है
हिमांशु आहूजा

-1

बाईं ओर x (बाईं ओर) असाइन करने के बाद बाईं ओर असाइनमेंट में दूसरी तुलना करना आसान है। फिर आप 3 == 3 से तुलना कर रहे हैं। पहले उदाहरण में आप नए असाइन x = 3 के साथ x = 1 की तुलना कर रहे हैं। ऐसा लगता है कि हमेशा वर्तमान स्थिति पढ़ने के बयानों को x के बाएं से दाएं की ओर ले जाया जाता है।


-2

यदि आपने जावा कंपाइलर लिखना चाहते हैं या जावा कंपाइलर सही तरीके से काम कर रहा है, यह जांचने के लिए प्रोग्राम का परीक्षण करना चाहते हैं तो इस तरह का प्रश्न बहुत अच्छा प्रश्न है। जावा में, इन दो अभिव्यक्तियों को आपके द्वारा देखे गए परिणामों का उत्पादन करना चाहिए। C ++ में, उदाहरण के लिए, उनके पास ऐसा करने के लिए नहीं है - इसलिए यदि कोई अपने जावा कंपाइलर में C ++ कंपाइलर के कुछ हिस्सों का पुन: उपयोग करता है, तो आप सैद्धांतिक रूप से यह पा सकते हैं कि कंपाइलर को वैसा व्यवहार नहीं करना चाहिए जैसा कि उसे करना चाहिए।

एक सॉफ्टवेयर डेवलपर के रूप में, ऐसा कोड लिखना जो पठनीय, समझने योग्य और बनाए रखने योग्य हो, आपके कोड के दोनों संस्करणों को भयानक माना जाएगा। यह समझने के लिए कि कोड क्या करता है, किसी को यह जानना होगा कि जावा भाषा कैसे परिभाषित है। कोई है जो जावा और सी ++ कोड दोनों लिखता है कोड को देखकर कंपकंपी होगी। यदि आपको यह पूछना है कि कोड की एक भी रेखा ऐसा क्यों करती है, तो आपको उस कोड से बचना चाहिए। (मुझे लगता है और आशा है कि जो लोग आपके "क्यों" प्रश्न का सही उत्तर देंगे, वे स्वयं भी कोड के उस इंड से बच जाएंगे)।


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