2011-10-28 17 views
31
if(a && b) 
{ 
    do something; 
} 

क्या दाएं से बाएं (बी -> ए) से तर्कों का मूल्यांकन करने की कोई संभावना है?"आईएफ" तर्क मूल्यांकन आदेश?

यदि "हाँ", मूल्यांकन आदेश को क्या प्रभावित करता है?

(मैं VS2008 उपयोग कर रहा हूँ)

+9

'अगर (ख && क)' यह तुम्हारे लिए क्या करेंगे। –

+1

'ए' और' बी' क्या हैं? –

+0

कोशिश करें अगर (बी एंड ए)। इस लिंक को आजमाएं: http://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx – CloudyMarble

उत्तर

37

मूल्यांकन आदेश मानक द्वारा निर्दिष्ट किया गया है और left-to-right है। बाईं ओर सबसे अधिक अभिव्यक्ति का मूल्यांकन पहले && खंड के साथ किया जाएगा।

आप b चाहते हैं पहले मूल्यांकन किया जाना:

if(b && a) 
{ 
    //do something 
} 

दोनों बहस तरीके हैं और आप चाहते हैं उन दोनों को उनके परिणाम की परवाह किए बिना मूल्यांकन किया जाना:

bool rb = b(); 
bool ra = a(); 

if (ra && rb) 
{ 
    //do something 
} 
+3

यह एक राहत है ... एक बार सी ++ के पास आश्चर्यजनक रूप से अस्पष्ट एक –

+3

@AviadRozenhek के बजाय सही डिफ़ॉल्ट व्यवहार होता है: आप डरने का अधिकार रखते हैं क्योंकि वास्तव में यह संभव है कि अभिव्यक्ति 'बी' का अभिव्यक्ति 'ए' से पहले मूल्यांकन किया जाए। ऐसा होने के लिए हालांकि ऑपरेटर को पूर्वनिर्धारित '&&' तार्किक-और ऑपरेटर नहीं होना चाहिए, लेकिन उपयोगकर्ता द्वारा परिभाषित प्रकारों के लिए अधिभार होना चाहिए।उस स्थिति में तर्कों के मूल्यांकन का आदेश अनिर्दिष्ट है (और इससे भी बदतर है कि आप वास्तविक आदेश की अपेक्षा भी नहीं कर सकते क्योंकि मूल्यांकन "इंटरमीक्स" भी हो सकता है: कुछ 'ए', फिर कुछ' बी ', फिर 'ए' के अधिक, फिर फिर' बी' के कुछ शेष बिट्स और अंततः कस्टम ऑपरेटर को बुलाया जाता है)। – 6502

+0

इसके बजाय यदि '||' का उपयोग किया जाता है तो क्या मामला है? यह _should_ वही रहता है जब तक कि कुछ कंपाइलर अनुकूलन इसे iu, सही @ 6502 गंक न करें? – mdw7326

7

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

यदि a झूठा लौटाता है, तो b पर मूल्यांकन करने की अनुमति नहीं है।

+1

... जब तक 'ऑपरेटर &&' अधिभारित नहीं होता है। जो संभव है, लेकिन खराब डिजाइन के रूप में माना जाता है। – dalle

+0

मैंने इसके बारे में नहीं सोचा था। अच्छी बात। :) – Mysticial

+0

मुझे सबसे निश्चित बात है कि निम्नलिखित मामला है लेकिन यह ऐसा कुछ करने के लिए सुरक्षित है: 'Obj * obj; अगर (obj && obj-> foo()) {...} ' मुझे लगता है कि यह जांचता है कि यह wheter obj पूर्ण नहीं है और केवल अगर यह शून्य नहीं है, तो यह 'obj-> foo()' के परिणाम की जांच करेगा, सही? –

2

यह मूल्यांकन से बाएं से दाएं और शॉर्ट सर्किट का मूल्यांकन करेगा (उदाहरण के लिए यदि झूठ का मूल्यांकन यह मूल्यांकन नहीं करेगा)।

यदि आप उस ऑर्डर की परवाह करते हैं जिसका मूल्यांकन आप में किया जाता है तो आपको अपने कथन में मूल्यांकन के वांछित क्रम में निर्दिष्ट करने की आवश्यकता है।

+0

प्रश्न सी ++ के बारे में है, सी # नहीं (हालांकि आप शायद सही हैं कि दोनों एक ही काम करते हैं, जो सी से प्रेरित है)। –

+0

ओह! मुझे लगता है कि वे वही हैं जैसा आप कहते हैं। –

44

सी के साथ देखते हैं ++ केवल कुछ ऑपरेटर जो मूल्यांकन आदेश

  • की गारंटी देते हैंपहले बाएं ऑपरेंड का मूल्यांकन करता है और यदि मान तार्किक रूप से false है तो यह सही ऑपरेंड का मूल्यांकन करने से बचाता है। विशिष्ट उपयोग उदाहरण के लिए if (x > 0 && k/x < limit) ... है जो शून्य समस्याओं से विभाजन से बचाता है।

  • operator || पहले बाएं ऑपरेंड का मूल्यांकन करता है और यदि मान तार्किक रूप से true है तो यह सही ऑपरेंड का मूल्यांकन करने से बचाता है। उदाहरण के लिए if (overwrite_files || confirm("File existing, overwrite?")) ... ध्वज overwrite_files सेट होने पर पुष्टि नहीं पूछेगा।

  • operator , बाएं ऑपरेंड का मूल्यांकन करता है और फिर दाएं ऑपरेंड का मूल्य लौटाता है, फिर भी सही ऑपरेंड का मूल्यांकन करता है। इस ऑपरेटर का अक्सर उपयोग नहीं किया जाता है। ध्यान दें कि फ़ंक्शन कॉल में पैरामीटर के बीच कॉमा अल्पविराम ऑपरेटरों और मूल्यांकन के आदेश की गारंटी नहीं है।

  • त्रिगुट ऑपरेटर x?y:z मूल्यांकन करता x पहले, और फिर परिणाम के तार्किक मूल्य के आधार पर या तो केवल y या केवल z मूल्यांकन करता है।

अन्य सभी ऑपरेटरों के लिए मूल्यांकन का आदेश निर्दिष्ट नहीं है।

स्थिति वास्तव में बदतर है क्योंकि यह है कि आदेश निर्दिष्ट नहीं है नहीं है, लेकिन वहाँ बिल्कुल अभिव्यक्ति के लिए एक "आदेश" भी नहीं है कि, और

std::cout << f() << g() << x(k(), h()); 

में उदाहरण के लिए यह संभव है कि कार्यों h-g-k-x-f क्रम में बुलाया जाएगा (यह थोड़ा परेशान है क्योंकि << ऑपरेटर का मानसिक मॉडल किसी भी तरह अनुक्रमिकता का विचार बताता है लेकिन वास्तविकता में अनुक्रम का केवल क्रम में परिणामों को धारा में रखा जाता है और न कि परिणाम में गणना)।

जाहिर है अभिव्यक्ति में मूल्य निर्भरता कुछ आदेश गारंटी लागू कर सकती है; उदाहरण के लिए उपर्युक्त अभिव्यक्ति में यह गारंटी है कि k() और h() दोनों को x(...) से पहले बुलाया जाएगा क्योंकि x पर कॉल करने के लिए दोनों से वापसी मूल्यों की आवश्यकता है।

यह भी ध्यान दें कि &&, || और , के लिए गारंटी केवल पूर्वनिर्धारित ऑपरेटरों के लिए मान्य है। यदि आप अपने ऑपरेटरों के लिए उन ऑपरेटरों को अधिभारित करते हैं तो वे सामान्य कार्य कॉल जैसे मामले में होंगे और ऑपरेटरों के मूल्यांकन के आदेश को निर्दिष्ट नहीं किया जाएगा।

+1

बस एक नाइट, लेकिन मूल्य निर्भरता भी एक आदेश लगाया। '(ए + बी) * सी',' ए 'और' बी 'जैसी अभिव्यक्ति में अतिरिक्त होने से पहले मूल्यांकन किया जाना चाहिए, और गुणा से पहले जोड़ा जाना चाहिए। आम तौर पर, यह प्रभाव अनावश्यक है, लेकिन अगर ऑपरेटर ओवरलोड हो जाते हैं, तो यह दिखाई दे सकता है। –

+0

@JamesKanze: ठीक है। मुझे लगता है कि यह सी ++ जैसी भाषा के लिए स्पष्ट है, लेकिन इसके लिए एक नोट भी जोड़ा गया है। – 6502

3

पहले (बाएं) के तर्क का हर मूल्य गणना और पक्ष प्रभाव में निर्मित तार्किक AND ऑपरेटर & & और निर्मित तार्किक OR ऑपरेटर || प्रत्येक मूल्य गणना और दूसरे (दाएं) तर्क के साइड इफेक्ट से पहले अनुक्रमित किया जाता है।

यहाँ नियम निर्धारित की एक और अधिक संपूर्ण विवरण के लिए पढ़ें: order evaluation

1

&& ऑपरेटर हमेशा अपनी बाईं संकार्य पहले मूल्यांकन करता है। उदाहरण के लिए:

if (a && b) 
{ 
    //block of code 
} 

a यदि गलत है, तो b का मूल्यांकन नहीं किया जाएगा।

यदि आप चाहते हैं b पहले मूल्यांकन किया जाना है, और a केवल तभी b सच है, बस अभिव्यक्ति दूसरी तरह के आसपास लिखें:

if (b && a) 
{ 
    //block of code 
} 
संबंधित मुद्दे