2010-10-02 15 views
13
int x=1; 
int y=2; 
x ^= y ^= x ^= y; 

मुझे मूल्यों को बदलने की उम्मीद है। लेकिन यह x = 0 और y = 1 देता है। जब मैंने सी भाषा में कोशिश की तो यह सही परिणाम देता है।यह कथन जावा x^= y^= x^= y में क्यों काम नहीं कर रहा है;

+4

यह सी में अपरिभाषित व्यवहार है, क्योंकि आप दोनों अनुक्रम बिंदु में x और y दोनों को संशोधित कर रहे हैं। –

+3

इसका उपयोग न करें। स्वैप 2 के लिए एक अतिरिक्त अस्थायी चर का उपयोग करना अधिक कुशल है क्योंकि इसे गणना करना नहीं है। –

+1

@Imre: मैं आपका सुझाव लेगा। –

उत्तर

56

अपने बयान मोटे तौर पर यह विस्तृत रूप के बराबर है:

x = x^(y = y^(x = x^y)); 

सी के विपरीत, जावा में एक द्विआधारी ऑपरेटर के बाईं संकार्य गारंटी है सही संकार्य से पहले मूल्यांकन किया जाना। मूल्यांकन इस प्रकार होती है:

x = x^(y = y^(x = x^y)) 
x = 1^(y = 2^(x = 1^2)) 
x = 1^(y = 2^(x = 3)) 
x = 1^(y = 2^3)    // x is set to 3 
x = 1^(y = 1) 
x = 1^1      // y is set to 1 
x = 0       // x is set to 0 

आप प्रत्येक XOR अभिव्यक्ति करने के लिए तर्क का क्रम उलटने से पहले चर फिर से मूल्यांकन किया जाता है ताकि काम किया जाता है:

x = (y = (x = x^y)^y)^x 
x = (y = (x = 1^2)^y)^x 
x = (y = (x = 3)^y)^x 
x = (y = 3^y)^x    // x is set to 3 
x = (y = 3^2)^x 
x = (y = 1)^x 
x = 1^x      // y is set to 1 
x = 1^3 
x = 2       // x is set to 2 

यह एक अधिक कॉम्पैक्ट संस्करण है यह भी काम करता है:

x = (y ^= x ^= y)^x; 

लेकिन यह दो चरों को स्वैप करने का एक बहुत ही भयानक तरीका है। अस्थायी चर का उपयोग करना एक बेहतर विचार है।

+11

+1। –

+1

+1 वाह - अच्छा जवाब। – duffymo

+0

क्या आप निश्चित हैं? मैंने सोचा कि एक असाइनमेंट सच हो गया है, यही कारण है कि अगर = = हमेशा के लिए कथन कहां इस्तेमाल किया गया था? इसका मतलब यह होगा कि आपका पहला कथन x = x^true^true जैसा ही था; – AaronM

13

मार्क जावा में इसका मूल्यांकन करने के तरीके के बारे में बिल्कुल सही है। कारण JLS §15.7.2. है, ऑपरेशन से पहले ऑपरेंड मूल्यांकन, और §15.7, जो मूल्यांकन की आवश्यकता है बाएं से दाएं:

यह (§15.26.2 द्वारा, यौगिक असाइनमेंट ऑपरेटरों) के बराबर है:

x = x^(y = y^(x = (x^y))); 

हम बाएं से दाएं मूल्यांकन , ऑपरेशन से पहले दोनों ऑपरेटरों कर रहे हैं।

x = 1^(y = y^(x = (x^y))); // left of outer 
x = 1^(y = 2^(x = (x^y))); // left of middle 
x = 1^(y = 2^(x = (1^y))); // left of inner 
x = 1^(y = 2^(x = (1^2))); // right of inner 
x = 1^(y = 2^(x = 3)); // inner xor (right inner assign) 
x = 1^(y = 2^3); // inner assign (right middle xor) 
x = 1^(y = 1); // middle xor (right middle assign) 
x = 1^1; // middle assign (right outer xor) 
x = 0; // outer xor (right outer assign) 

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

+1

+1। –

संबंधित मुद्दे