2011-12-20 18 views
59

मैं थोड़ा उलझन में हूं कि कैसे सी # कंपाइलर पूर्व-और वृद्धि और कमी पोस्ट करता है।सी # प्री- और पोस्ट वृद्धि भ्रम

जब मैं निम्नलिखित कोड:

int x = 4; 
x = x++ + ++x; 

x मूल्य 10 बाद में होगा। मुझे लगता है कि ऐसा इसलिए है क्योंकि प्री-एन्हांसमेंट x से 5 सेट करता है, जो इसे 5+5 बनाता है जो 10 का मूल्यांकन करता है। फिर पोस्ट-वृद्धि x6 पर अपडेट हो जाएगी, लेकिन इस मान का उपयोग नहीं किया जाएगा क्योंकि 10 को x पर असाइन किया जाएगा।

लेकिन जब मैं कोड:

int x = 4; 
x = x-- - --x; 

तो x2 बाद में किया जाएगा। क्या कोई यह समझा सकता है कि यह मामला क्यों है?

+2

शानदार सवाल! और हमने कभी भी ऐसा कोड नहीं सीखा है जिसे आप सोच सकते हैं कि यह क्या कर सकता है, लेकिन यह क्या करेगा। – RvdK

+15

कोई भी जो इस तरह के कोड लिखता है उसे बाहर निकाला और गोली मार दी जानी चाहिए। 'X = x ++ +++ x;' ... के लिए कोई बहाना नहीं है। –

+15

यह सिर्फ एक "अकादमिक" प्रश्न था - मैं इस तरह के कोड को कभी भी नहीं लिखूंगा :-) – Schweder

उत्तर

46

x-- 4 होगा, लेकिन --x के पल में 3 हो जाएगा, तो यह जा रहा है 2 खत्म हो जाएगा, तो आप

x = 4 - 2 

Btw, अपने पहले मामले हो जाएगा होगा x = 4 + 6

यहां एक छोटा उदाहरण है जो प्रत्येक भाग के मानों को प्रिंट करेगा, शायद इस तरह आप इसे बेहतर समझेंगे:

static void Main(string[] args) 
{ 
    int x = 4; 
    Console.WriteLine("x++: {0}", x++); //after this statement x = 5 
    Console.WriteLine("++x: {0}", ++x); 

    int y = 4; 
    Console.WriteLine("y--: {0}", y--); //after this statement y = 3 
    Console.WriteLine("--y: {0}", --y); 

    Console.ReadKey(); 
} 

यह प्रिंट ओ केन्द्र शासित प्रदेशों के

x++: 4 
++x: 6 
y--: 4 
--y: 2 
+3

आपके उत्तर के लिए धन्यवाद - मैंने सोचा कि पोस्ट- और पूर्व-वृद्धि को पूर्ण कोडलाइन के मूल्यांकन के पहले/पहले निष्पादित किया जाता है - लेकिन अभिव्यक्ति में प्रत्येक आइटम के मूल्यांकन के बाद उन्हें/पहले निष्पादित किया जाता है। – Schweder

+0

@Schweder, मामूली सुधार: ऑपरेटर को वैरिएबल के मूल्यांकन के बाद/पहले निष्पादित किया जाता है, जिस पर उन्हें लागू किया गया है। अभिव्यक्ति में प्रत्येक शब्द नहीं। – Amy

+2

@Inuyasha: आपके सुधार में सुधार: चर के रूप में चर के मूल्यांकन के बाद ऑपरेटर * हमेशा * निष्पादित * होते हैं। प्री और पोस्ट ऑपरेटरों के बीच का अंतर केवल * मूल्य वापस लौटाया गया है, न कि * जिस क्रम में ऑपरेशन किए जाते हैं *। –

-1

मुझे लगता है कि ++ + ++ मामले के लिए स्पष्टीकरण गलत है: एक्स

की

आदेश ........... मूल्य

.... .............. अपरिभाषित

पूर्णांक एक्स = 4 .......... 4

x ++ ........... .... 5 (पहला सारांश 4 है)

(6 दूसरा योज्य है) ++ x ............... 6

एक्स = summand1 + summand2 ..4 + 6 = 10

अनुरूप के लिए विवरण - - - मामले ..................

आदेश ........... एक्स

का मूल्य है अपरिभाषित

(4 subtactor है)

पूर्णांक एक्स = 4 .......... 4

एक्स --............... 3

--x ............... 2 (सबट्रेंड 2 है)

x = subtractor-subtrahend ..4-2 = 10

+0

मुझे समझ में नहीं आया कि आप बिल्कुल जवाब देते हैं, क्षमा करें। –

+0

@phresnel मैंने जवाब में कुछ गलतियों को सही किया। वह मूल रूप से आपके द्वारा स्वीकार किए गए उत्तर के समान ही कह रहा है: हम वास्तव में 10 प्राप्त कर रहे हैं क्योंकि हम 4 और 6 जोड़ रहे हैं; 2 4 और 2. – phoog

16

आईएल कि बयान से उत्पन्न हो जाता है कि

IL_0002: ldloc.0  

भार ढेर पर एक्स का मान पर एक नजर है की सुविधा देता है। स्टैक => (4)

IL_0003: dup   

ढेर पर सबसे ऊपर की वस्तु डुप्लिकेट करता है। स्टैक => (4, 4)

IL_0004: ldc.i4.1  

स्टैक पर 1 पुश करें। स्टैक => (1, 4, 4)

IL_0005: sub   

दो शीर्ष मान घटाएं और स्टैक पर पुश परिणाम घटाएं। स्टैक => (3, 4)

IL_0006: stloc.0  

स्टैक के शीर्ष मूल्य को x पर वापस स्टोर करें। स्टैक => (4)

IL_0007: ldloc.0  

एक्स के मान को वापस ढेर में लोड करें। ढेर => (3, 4)

IL_0008: ldc.i4.1  

लोड ढेर पर मान 1। स्टैक => (1, 3, 4)

IL_0009: sub   

दोनों घटाएं। ढेर => (2, 4) शीर्ष मूल्य => (2, 2, 4)

IL_000B: stloc.0  

स्टोर शीर्ष मूल्य वापस एक्स के लिए

IL_000A: dup   

डुप्लिकेट। स्टैक => (2, 4)

IL_000C: sub  

दो शीर्ष मान घटाएं। स्टैक => (2)

IL_000D: stloc.0 

इस मान को वापस x में स्टोर करें। एक्स == 2

2

इस उदाहरण में,

int x = 4; 
x = x++ + ++x; 

आप इसे पसंद तोड़ सकते हैं:

x = 4++; which is = 5 
x = 4 + ++5; which is 4 + 6 
x = 10 

इसी तरह,

int x = 4; 
x = x-- - --x; 

यहाँ,

x = 4--; which is = 3 
x = 4 - --3; which is 4 - 2 
x = 2 

बस आप कह सकते हैं, एक्स के वर्तमान मान को प्रतिस्थापित करें, लेकिन प्रत्येक ++ या - x से मान को घटाएं/घटाएं।

6

सबसे दिलचस्प बात यह है कि आपको सी ++ के साथ एक पूरी तरह से अलग जवाब मिलेगा। नेट कंपाइलर।

int x = 4; 
x = x++ + ++x; // x = 11 
x = 4; 
x = x-- - --x; // x = -1 

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

+2

के बीच का अंतर है C++ (सी ++ के माइक्रोसॉफ्ट के गैर-सी ++ संस्करणों में से एक नहीं) में, पूर्ण अभिव्यक्ति के अंत से पहले एक चर को संशोधित करना अपरिभाषित व्यवहार उत्पन्न करता है। –

+4

इसमें * पार्स * के साथ कुछ भी नहीं है। अनुक्रम बिंदुओं के संबंध में इसे दो भाषाओं के विभिन्न अनुमत अर्थशास्त्र के साथ करना है। –

8

अपनी टिप्पणी से:

मैंने सोचा था कि पोस्ट और पूर्व वेतन वृद्धि के बाद क्रियान्वित कर रहे हैं/पूरा codeline के मूल्यांकन से पहले - लेकिन वे क्रियान्वित कर रहे हैं अभिव्यक्ति में प्रत्येक आइटम के मूल्यांकन से पहले के बाद /।

आपकी गलतफहमी बेहद आम है। ध्यान दें कि कुछ भाषाओं में, सी की तरह, यह निर्दिष्ट नहीं किया जाता है जब साइड इफेक्ट दिखाई देता है और इसलिए यह कानूनी है, लेकिन आवश्यक नहीं है, क्योंकि आपके कथन में सी

यह सी # में नहीं है; सी # में एक अभिव्यक्ति की बाईं ओर स्थित कोड की दुष्प्रभाव हमेशा सही पक्ष पर कोड से पहले होने की मनाया जाता है कार्यान्वित (एक धागे से; बहु परिदृश्यों में सभी दांव बंद कर रहे हैं।)

एक अधिक विस्तृत के लिए क्या वेतन वृद्धि ऑपरेटरों सी # में क्या का विवरण, देखें:

What is the difference between i++ and ++i?

एक महान कई अतिरिक्त लेख मैं इस बार-गलत समझा विषय पर लिखा है करने के लिए वहाँ लिंक मौजूद हैं।