2010-01-05 7 views
9

तो क्या कोई मुझे किसी (या) (जबकि), आदि जैसे किसी असाइनमेंट की सभी (या अधिक प्रासंगिक) परिस्थितियों को समझने में मदद कर सकता है?सी ++ में नियंत्रण संरचना में उपयोग किए जाने पर वास्तविक या गलत के रूप में मूल्यांकन करने के लिए असाइनमेंट का कारण क्या होता है?

क्या मेरा मतलब है की तरह है:

if(a = b) 

या

while(a = &c) 
{ 
} 

आदि ...

जब यह रूप में सही मूल्यांकन करेंगे, और जब यह के रूप में झूठी मूल्यांकन करेंगे? क्या यह असाइनमेंट में उपयोग किए गए प्रकारों के आधार पर बिल्कुल बदलता है? पॉइंटर्स में शामिल होने के बारे में क्या?

धन्यवाद।

उत्तर

15

C++ में एक रोपण मूल्य का आकलन करती माने जा:

int c = 5; // evaluates to 5, as you can see if you print it out 
float pi = CalculatePi(); // evaluates to the result 
          // of the call to the CalculatePi function 

तो, आप बयान:

a = b 
if (b) { } 
a = &c 
while (&c) { } 

जो एक ही कर रहे हैं:

if (a = b) { } 
while (a = &c) { } 

मोटे तौर पर के बराबर हैं

के रूप में

और क्या उन if (a) आदि जब वे बूलियन्स नहीं कर रहे हैं के बारे में? खैर, अगर वे पूर्णांक हैं, 0 झूठा है, बाकी सच है। यह (एक "शून्य" मूल्य -> ​​झूठी, बाकी -> सच) आम तौर पर रखती है, लेकिन तुम सच में ++ संदर्भ एक सी का संदर्भ लेना चाहिए सुनिश्चित करने के लिए (हालांकि ध्यान दें कि writting if (a == 0) ज्यादा if (!a) की तुलना में अधिक मुश्किल नहीं है, ज्यादा किया जा रहा है पाठक के लिए आसान)।

वैसे भी, आपको हमेशा अपने प्रभाव को अस्पष्ट करने वाले दुष्प्रभावों से बचना चाहिए।

आप चाहिए कभी नहींif (a = b) करने की ज़रूरत: आप अन्य तरीकों कि और अधिक स्पष्ट कर रहे हैं और कहा कि एक गलती की तरह नहीं होगा (अगर मैं पहली बात यह आता है कि if (a = b) की तरह एक कोड को पढ़ने में बिल्कुल वही बात प्राप्त कर सकते हैं दूसरे, अगर मैं ट्रिपल जांच करें कि यह सही है, कि मैं उसे नफरत है

गुड लक

+2

एक स्टाइल सम्मेलन के रूप में, अधिकांश कंपाइलर इस मामले के लिए चेतावनी जारी करते हैं (कुछ "बूलियन संदर्भ में असाइनमेंट" या "क्या आपका मतलब ==?") है, और कई लोग इस शैली का उपयोग करते हैं कि असाइनमेंट-ए-टेस्ट एक्सप्रेशन जानबूझकर है: 'अगर ((ए = बी)) {...}' – greyfade

+2

मैं व्यक्तिगत रूप से 'अगर (static_cast (ए = बी)) {} '- निहित कास्ट स्पष्ट बना देता हूं। कुछ पागल अधिभार ऑपरेटर के मामले में – MSalters

+0

= किसी अन्य संदर्भ को वापस कर सकता है, जो कि (ए = बी) ए के बराबर नहीं है। ऑफसी, उस मामले में हमें लेखक की संवेदना – Swift

1

असाइनमेंट का रिटर्न प्रकार बाएं हाथ का मान है, यह संकलन के लिए a = b = c जैसे बयान की अनुमति देता है। अपने उदाहरण में:

while(a = &c) 
{ 
} 

रिटर्न सच है जब बाद यह & ग का मूल्य सौंपा गया है "एक" सच है, है।

+0

या nonzero, साथ ही साथ। – bmargulies

+0

यह * नया * बाएं हाथ का मूल्य है (या बेहतर कहा गया है, असाइनमेंट का * परिणाम *) –

+0

+1 ... स्पष्टीकरण में सहायता के लिए, आपकी अभिव्यक्ति को अभिन्न मान में परिवर्तित कर दिया जाएगा, और यदि यह शून्य है , कथन का मूल्यांकन 'सत्य' के रूप में किया जाएगा, यदि यह शून्य है, तो झूठी है। – Mongoose

0

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

एक और आम मामले में, आप इस समस्या से बचने के लिए एक चर के साथ एक चर की तुलना करते हैं, कुछ कोडिंग मानकों की आवश्यकता होती है कि आप पहले स्थिर लिखें।

अगर (A_CONSTANT = var_a)

इस, संकलक द्वारा पकड़ा किया जाएगा, जबकि

अगर (var_a = A_CONSTANT)

नहीं होगा।

+0

कुछ कंपाइलर चेतावनी निदान जारी करते हैं। शायद डिफ़ॉल्ट रूप से नहीं, लेकिन निश्चित रूप से उच्च चेतावनी के स्तर पर। – greyfade

5

एक असाइनमेंट "ऑपरेशन" भी एक मूल्य देता है। यह अभिव्यक्ति का प्रकार और मूल्य है।

  • while (expr)
  • do ... until (expr)
  • if (expr)
  • या त्रिगुट ऑपरेटर (expr) ? (सही मूल्य):: यदि एक if प्रकार बयान ने संभाला झूठी मूल्य

expr का मूल्यांकन किया जाता है। यदि यह nonzero है, यह सच है। यदि शून्य है, तो यह झूठा है।

0
if (a = b) 
    ... 

है :-); मेरे मन है कि developper जो लिखा है कि एक गलती की है! आशुलिपि के लिए:

a = b; 
if (a != 0) 
    ... 

थोड़ी देर के बयान में हालत के भीतर काम में सक्षम बनाता है DRY सिद्धांत:

while (a = b) 
{ 
    ... 
} 

के लिए (ध्यान दें कि किस मैं काम को दोहराने के लिए इतना है कि यह हालत की जांच करने से पहले सही किया जाता है था) आशुलिपि है:

a = b; 
while (a != 0) 
{ 
    ... 
    a = b; 
} 

जिसके अनुसार, इस तरह कोड कोड एक काम क्या करने का इरादा है या जानते हुए भी है के साथ एक क्लासिक मुद्दा कोड भूल जाते हैं एक '=' इरादे लिखने के लिए '==' (यानी था जब यह होना चाहिए while (a == b)

इस वजह से

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

if ((a = b) != 0) 
    ... 

while ((a = b) != 0) 
    ... 
+0

एक विश्व स्तरीय पुरस्कार विजेता 'कैसे-लिखने-लिखने-कोड' और 'कोड-वह-लगता-एक-गलती' का अद्भुत उदाहरण है। –

+2

शायद उपर्युक्त के रूप में बिल्कुल नहीं बताया गया है, लेकिन मुझे लगता है कि कुछ समय के भीतर असाइनमेंट के साथ कोड() समझ में आता है ... विशेष रूप से कुछ ऐसा (पी = enumerate_frobs (& frob_state)) {...} जहां नाम ऐसा कुछ बनाता है स्पष्ट है कि यह एक इटरेटर-आश पैटर्न का पालन करता है। इस बात को ध्यान में रखते हुए यह केवल डाउनवोट को अनुचित लगता है क्योंकि उत्तर कुछ ऐसा वर्णन कर रहा है जिसे * दुरुपयोग किया जा सकता है लेकिन इसका भी अच्छा उपयोग हो सकता है। – asveikau

0

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

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

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