शॉर्ट सर्किट या दोनों के साथ-साथ C # में उस ऑपरेटर की अशिक्षित-परिचालित भिन्नता क्यों है?


9

समय-समय पर मुझे इस बारे में आश्चर्य होता है:

शॉर्ट-सर्किट या हमेशा वही मान लौटाएगा जो अनशर्ट-सर्कुलेटेड OR ऑपरेटर करेगा?

मुझे उम्मीद है कि शॉर्ट-सर्किट या हमेशा अधिक तेज़ी से मूल्यांकन करेगा। तो, निरंतरता के लिए सी # भाषा में अनशर्ट-सर्कुलेटेड OR ऑपरेटर को शामिल किया गया था?

मुझे क्या याद किया?


9
समान वापसी मूल्य - हाँ। समान दुष्प्रभाव - नहीं।
जॉब

2
मान लीजिए कि f()एक अपवाद है, विचार करें true || f()और true | f()। आपको फर्क दिखता हैं? पूर्व अभिव्यक्ति का मूल्यांकन किया जाता है true, एक अपवाद के बाद के परिणामों का मूल्यांकन फेंका जा रहा है।
स्कारफ्रिज

जवाबों:


25

दोनों ऑपरेशंस अलग-अलग चीजों के लिए थे, सी से आ रहे थे जिनमें बूलियन प्रकार नहीं था। शॉर्ट-सर्किट संस्करण || केवल बूलियंस के साथ काम करता है, जबकि गैर-शॉर्ट सर्किट संस्करण | अभिन्न प्रकार के साथ काम करता है, एक बिटवाइज़ या प्रदर्शन करता है। यह सिर्फ बूलियन्स के लिए एक गैर-शॉर्ट सर्किट लॉजिकल ऑपरेशन के रूप में काम करने के लिए हुआ, जो कि 0 या 1 के होते हुए, एकल बिट द्वारा दर्शाया जाता है।

http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators#Logical


10
लिंक के लिए +1। जब मैंने इस प्रश्न को पढ़ा तो मैं "क्या?" चूँकि इनका आधिकारिक नाम तार्किक और बिटवाइज़ है या, न कि शॉर्ट-सर्किट और अनशॉर्ट-सर्किट, जो कि उनके काम करने के दुष्परिणाम होते हैं।
१०

1
+1 मैं देखता हूं कि "बूलियन ऑपरेंड्स पर ही संचालित होता है" - मैंने संभवतः अंतर पर ध्यान नहीं दिया क्योंकि मैं केवल उन अभिव्यक्तियों का उपयोग करता हूं जो वैसे भी बूलियन का मूल्यांकन करते हैं
कार्नेकोड

2
मुझे जांच करनी थी, लेकिन यह वास्तव में सच है कि |ऑपरेटर, जब दो बुलियन मूल्यों पर लागू होता है, तो orसीआईएल में उसी ऑपरेटर में संकलित किया जाता है जब यह दो पूर्णांक मानों पर लागू होता है - ||जिसके विपरीत brtrueएक सशर्त का उपयोग करके सीआईएल में संकलित किया जाता है कूद।
क्वेंटिन-स्टारिन

13

|(बिटवाइज़-या) जैसे प्रकारों के लिए गैर-शॉर्ट-सर्किट होना चाहिए int। ऐसा इसलिए है क्योंकि लगभग सभी मामलों में आपको |सही परिणाम की गणना करने के लिए अभिव्यक्ति के दोनों किनारों की गणना करने की आवश्यकता होती है । उदाहरण के लिए, परिणाम क्या है 7 | f(x)?

यदि f(x)मूल्यांकन नहीं किया गया है, तो आप नहीं बता सकते।

इसके अलावा इस ऑपरेटर को शॉर्ट-सर्किट बनाना असंगत होगा bool, जब यह गैर-शॉर्ट-सर्किट के लिए हो int। वैसे, मुझे लगता है कि मैंने कभी भी |तार्किक तुलना के लिए जानबूझकर उपयोग नहीं किया है , यह पाते हुए कि |तार्किक ऑपरेटर के रूप में बोलना बहुत असुविधाजनक है ।

|| हालाँकि तार्किक तुलना के लिए है, जहाँ शॉर्ट-सर्किट मूल्यांकन ठीक काम करता है।

सी और सी ++ के लिए भी वही मान्य है, जहां उन ऑपरेटरों की उत्पत्ति है।


5

यह सही है, शॉर्ट-सर्किट या ऑपरेटर (||) हमेशा गैर-शॉर्ट-सर्किट या ऑपरेटर ((।)) के समान मान लौटाएगा। (*)

हालांकि, यदि पहला ऑपरेंड सही है, तो शॉर्ट-सर्किट ऑपरेटर दूसरे ऑपरेंड के मूल्यांकन का कारण नहीं होगा, जबकि गैर-शॉर्ट-सर्किट ऑपरेटर हमेशा दोनों ऑपरेंड के मूल्यांकन का कारण होगा। यह प्रदर्शन पर प्रभाव डाल सकता है, और कभी-कभी दुष्प्रभाव में भी।

तो, दोनों के लिए एक उपयोग है: यदि आप प्रदर्शन के लिए परवाह करते हैं, और दूसरे ऑपरेंड के मूल्यांकन से कोई दुष्प्रभाव नहीं होता है, (या यदि आप उनकी परवाह नहीं करते हैं), तो हर तरह से शॉर्ट-सर्किट ऑपरेटर का उपयोग करें । लेकिन अगर किसी कारण से आपको दूसरे ऑपरेंड के साइड-इफेक्ट्स की आवश्यकता होती है, तो आपको गैर-शॉर्ट-सर्किट ऑपरेटर का उपयोग करना चाहिए।

एक उदाहरण जहां आपको गैर-शॉर्ट-सर्किट ऑपरेटर का उपयोग करना चाहिए:

if( write_customer_to_database() != SUCCESS |
    write_supplier_to_database() != SUCCESS |
    write_order_to_database() != SUCCESS )
{
    transaction_rollback();
}

(*) कुछ वास्तव में विकृत परिदृश्य को छोड़कर, जहां पहले ऑपरेंड का मूल्यांकन झूठे कारणों से होता है, दूसरे के लिए साइड-इफेक्ट के कारण गलत के बजाय सच का मूल्यांकन करने के लिए।


2
+1 लेकिन मैं यह जोड़ना चाहता हूं कि सफलता या असफलता (आपके उदाहरण के अनुसार) को इंगित करने के लिए फ़ंक्शंस का उपयोग करने के अलावा: साइड इफेक्ट्स वाले फ़ंक्शंस को आम तौर पर टाला जाना चाहिए ...
मार्जन वेनमा

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

यह उदाहरण सख्त बाएं से दाएं क्रम में मूल्यांकन किए जा रहे ऑपरेंड पर निर्भर करता है। C # इसकी गारंटी देता है, लेकिन कई समान भाषाएँ (C और C ++ सहित) ऐसा नहीं करती हैं।
कीथ थॉम्पसन

क्या शॉर्ट-सर्किट मूल्यांकन से उस विशेष उदाहरण का कोई मतलब नहीं होगा, क्योंकि यदि उनमें से कोई भी विफल हो जाता है तो सभी लेनदेन वापस आ जाएंगे? (मैं कॉल के शब्दार्थ के बारे में कुछ धारणाएँ बना रहा हूं।)
कीथ थॉम्पसन

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

4

गैर-शॉर्टसर्किट संस्करण का उपयोग करने के 2 कारण होंगे:

  1. साइड इफेक्ट रखने (लेकिन यह एक अस्थायी चर के साथ कोड करने के लिए स्पष्ट है)

  2. विफल समय हमलों शॉर्ट सर्किट में कांटा से परहेज द्वारा (यह और भी क्रम दक्षता में सुधार हो सकता है यदि दूसरे संकार्य एक चर रहा है, लेकिन यह एक सूक्ष्म अनुकूलन संकलक वैसे भी बना सकता है है)


यह केवल सही कारण प्रदान किया गया है, मुझे नहीं पता कि यह उच्चतम वोटों के साथ स्वीकृत उत्तर क्यों नहीं है ...
बेहरोज़

2

यदि ऑपरेटर के दाहिने हाथ के खंड का साइड-इफ़ेक्ट है, और प्रोग्रामर का इरादा है कि वह अपने रिटर्न वैल्यू की जाँच करने से पहले दोनों साइड इफेक्ट चाहता है।


5
EEK। कृपया ऐसा कोड न करें ... यदि आप साइड इफेक्ट पर भरोसा करते हैं, तो दो अलग-अलग अभिव्यक्तियाँ हैं, परिणाम असाइन करें, और बाद में उनका परीक्षण करें ।
कोनराड रुडोल्फ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.