क्यों '&&' और 'नहीं'?


135

के लिए &&बेहतर &और ||बेहतर क्यों है |?

मैंने किसी से पूछा जो वर्षों से प्रोग्रामिंग कर रहा है और उसकी व्याख्या थी:

उदाहरण के लिए, में if (bool1 && bool2 && bool3) { /*DoSomething*/ }, bool1परीक्षण करने के लिए इसके लिए सच हो गया है bool2जो पर जाने से पहले सच हो गया है bool3, आदि अगर मैं एक भी इस्तेमाल किया था &बजाय वहाँ परीक्षण भले ही उन सभी को सच हो करने के लिए कोई आदेश नहीं है अगली पंक्ति के लिए प्रगति, तो यह वैसे भी क्यों मायने रखता है?

नोट: मैं यह बताना चाहता हूं कि मैं एक बच्चा के प्रोग्रामिंग समकक्ष हूं और यह एक गंभीर या जरूरी सवाल नहीं है। यह समझने की बात अधिक है कि चीजों को एक निश्चित तरीके से दूसरे के विपरीत क्यों किया जाना चाहिए।


55
& && | और || पूरी तरह से अलग ऑपरेटर हैं
फेलिस पोलानो

3
रेट किया गया, क्योंकि यह केवल
जोनाथन डिकिंसन

12
उलटा, क्योंकि उत्तर पहले से ही C # के लिए विशिष्ट हैं और आंतरिक कामकाज अन्य भाषाओं में थोड़ा भिन्न हो सकते हैं जिनमें आम तौर पर समान अवधारणा होती है।
डैनियल हिल्गारथ

8
@ फेलिस: वे अलग हैं, लेकिन शायद ही पूरी तरह से अलग हैं। वे वास्तव में बहुत समान हैं: x & yऔर x && yहमेशा उसी परिणाम का मूल्यांकन करेंगे यदि एक्स और वाई बूलियन प्रकार के भाव हैं। वास्तव में उस मामले में एकमात्र अंतर यह प्रतीत होता है कि x & y, वाई का मूल्यांकन हमेशा किया जाता है।
जोरेन सेप

1
@slawekin: मैं उत्तर के माध्यम से पढ़ने का सुझाव दूंगा। कुछ बड़े पैमाने पर प्रदर्शन मतभेदों के बारे में लिखते हैं। जवाब आपको आश्चर्यचकित कर सकता है।
हाबिल

जवाबों:


183

ज्यादातर मामलों में, &&और ||अधिक पसंद किया जाता है &और |क्योंकि पूर्व कम-सर्कुलेटेड हैं, जिसका अर्थ है कि परिणाम स्पष्ट होते ही मूल्यांकन रद्द कर दिया जाता है।

उदाहरण:

if(CanExecute() && CanSave())
{
}

यदि CanExecuteरिटर्न false, पूर्ण अभिव्यक्ति होगी false, भले ही वापसी मूल्य की CanSave। इस वजह से, CanSaveनिष्पादित नहीं किया जाता है।

यह निम्नलिखित परिस्थितियों में बहुत आसान है:

string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
    // Do Something
}

TryGetValuefalseयदि प्रदत्त कुंजी शब्दकोश में नहीं मिली है तो वापस आती है । शॉर्ट-सर्कुलेटिंग नेचर के कारण &&, value.Contains("test")केवल निष्पादित किया जाता है, जब TryGetValueरिटर्न trueऔर इस तरह valueनहीं null। यदि आप इसके बजाय बिटवाइज़ और ऑपरेटर का उपयोग करते हैं &, तो आपको यह मिलेगा कि NullReferenceExceptionयदि शब्दकोश में कुंजी नहीं मिली है, क्योंकि अभिव्यक्ति का दूसरा भाग किसी भी मामले में निष्पादित होता है।

इसका एक समान लेकिन सरल उदाहरण निम्नलिखित कोड है (जैसा कि TJHeuvel द्वारा उल्लिखित है):

if(op != null && op.CanExecute())
{
    // Do Something
}

CanExecuteकेवल निष्पादित किया जाता है यदि opनहीं null। अगर opहै null, अभिव्यक्ति के पहले भाग ( op != null) का आकलन करती falseहै और बाकी के मूल्यांकन ( op.CanExecute()) को छोड़ दिया है।

इसके अलावा, तकनीकी रूप से, वे अलग हैं, भी:
&&और ||केवल पर इस्तेमाल किया जा सकता boolहै, जबकि &और |किसी भी अभिन्न प्रकार (पर इस्तेमाल किया जा सकता bool, int, long, sbyte,, ...), क्योंकि वे बिटवाइज़ ऑपरेटर्स हैं। &है बिटवाइज़ और ऑपरेटर और |है बिटवाइज़ या ऑपरेटर।

बहुत सटीक होने के लिए, C # में, उन ऑपरेटरों ( &, |[और ^]) को "लॉजिकल ऑपरेटर" कहा जाता है ( C # कल्पना , अध्याय 7.11 देखें)। इन ऑपरेटरों के कई कार्यान्वयन हैं:

  1. पूर्णांक के लिए ( int, uint, longऔर ulong, अध्याय 7.11.1):
    वे ऑपरेंड और ऑपरेटर की बिटवाइज़ परिणाम की गणना करने के लागू किया जाता है, यानी &बिटवाइज़ तार्किक गणना करने के लिए लागू है ANDआदि
  2. गणना के लिए (अध्याय 7.11.2):
    वे गणना के अंतर्निहित प्रकार के तार्किक संचालन को करने के लिए कार्यान्वित किए जाते हैं।
  3. बूल और अशक्त बूल के लिए (अध्याय 7.11.3 और 7.11.4): बिटवाइज
    गणना का उपयोग करके परिणाम की गणना नहीं की जाती है। परिणाम मूल रूप से दो ऑपरेंड के मूल्यों के आधार पर देखा जाता है, क्योंकि संभावनाओं की संख्या इतनी कम है।
    क्योंकि दोनों मानों को लुकअप के लिए उपयोग किया जाता है, यह कार्यान्वयन शॉर्ट-सर्किटिंग नहीं है।

31
यह जाँचने के लिए भी उपयोगी हो सकता है कि क्या कुछ अशक्त है। उदाहरण के लिए if(op != null && op.CanExecute()):। क्योंकि पहला isnt सही होने पर दूसरे कारण का मूल्यांकन नहीं किया जाता है, यह मान्य है।
TJHeuvel

2
@TJHeuvel: यह मूल रूप से एक ही उपयोग है जिसे मैंने अपने TryGetValueउदाहरण के साथ वर्णित किया है । लेकिन हां, इसका एक और अच्छा उदाहरण है।
डैनियल हिल्गर्थ

4
अच्छा उत्तर। हो सकता है कि आपको सभी व्यक्तियों के लाभ के लिए गैर-बूल तर्क (यानी ऑपरेटर क्या करते हैं) के साथ कैसे &या |इसका उपयोग किया जाता है, का एक उदाहरण जोड़ना चाहिए ।
ज़ब्बा

81

बहुत स्पष्ट रूप से यह समझाने के लिए कि इसका क्या अर्थ है (भले ही अन्य उत्तर उस पर संकेत दें - लेकिन संभवतः शब्दावली का उपयोग करें जो आपको समझ में नहीं आता है)।

निम्नलिखित कोड:

if (a && b)
{
   Foo();
}

वास्तव में इसके लिए संकलित है:

if (a)
{
    if (b)
    {
        Foo();
    }
}

जहां निम्न कोड को ठीक उसी तरह संकलित किया गया है, जैसा कि यह प्रतिनिधित्व करता है:

if (a & b)
{
   Foo();
}

इसे शॉर्ट-सर्कुइंग कहा जाता है। सामान्य तौर पर आपको हमेशा &&और ||अपनी स्थितियों में उपयोग करना चाहिए ।

बोनस मार्क्स: जब आपको ऐसा नहीं करना चाहिए तो एक परिदृश्य है। यदि आप ऐसी स्थिति में हैं जहां प्रदर्शन महत्वपूर्ण है (और यह नैनो-सेकंड महत्वपूर्ण है ) केवल शॉर्ट-सर्कुलेटिंग का उपयोग करें जब आपको आवश्यक होना चाहिए (उदाहरण के लिए nullचेकिंग) - शॉर्ट-सर्किट के रूप में एक शाखा / कूद है; जिसके परिणामस्वरूप आपके CPU पर एक शाखा-दुर्व्यवहार हो सकता है; a &काफी सस्ता है &&। एक परिदृश्य भी है जहां शॉर्ट-सर्कुलेटिंग वास्तव में तर्क को तोड़ सकता है - मेरा इस जवाब पर एक नज़र है ।

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

  • गेम डेवलपर्स (और अन्य वास्तविक समय की परिस्थितियों में काम करने वाले) जहां तक ​​बेहतर होगा, वे अपने तर्क को बेहतर बनाने के लिए भविष्यवक्ता के अनुकूल हैं। विघटित mscorlib कोड में इसका प्रमाण भी है।
  • सिर्फ इसलिए कि .NET इस प्रकार से आपको ढालता है इसका मतलब यह नहीं है कि यह महत्वपूर्ण नहीं है। एक शाखा गलत भविष्यवाणी 60 हर्ट्ज पर बहुत महंगी है; या 10,000 अनुरोध / सेकंड पर।
  • इंटेल के पास गलत-भविष्यवाणियों के स्थान की पहचान करने के लिए उपकरण नहीं होंगे, न ही विंडोज के लिए इसके लिए एक प्रदर्शन काउंटर होगा, और न ही इसका वर्णन करने के लिए एक शब्द होगा, क्या यह कोई समस्या नहीं थी।
  • निचले स्तरों और वास्तुकला के बारे में अज्ञानता किसी ऐसे व्यक्ति को नहीं बनाती है जो उनके बारे में गलत जानता है।
  • हमेशा उस हार्डवेयर की सीमाओं को समझने की कोशिश करें जिस पर आप काम कर रहे हैं।

यहाँ गैर-विश्वासियों के लिए एक बेंचमार्क है। इस प्रक्रिया को चलाने के लिए RealTime / High में सबसे अच्छा है कि शेड्यूलर को प्रभावी बनाने के लिए: https://gist.github.com/12003737


7
"बोनस चिह्नों" के बारे में: हम सभी अच्छे को जानते हैं जो समय से पहले अनुकूलन से निकलता है। :)
एक CVn

6
@ मिचेल - यही कारण है कि 'नैनो-सेकंड महत्वपूर्ण' बोल्ड में है :)। एएए गेम डेवलपर्स आमतौर पर इस तरह के सामान के बारे में चिंता करते हैं - और आप कभी नहीं जानते कि कौन जवाब पढ़ेगा; तो यह हमेशा सीमा रेखा / चरम मामलों पर भी दस्तावेज़ करने के लिए सबसे अच्छा है।
जोनाथन डिकिंसन

1
क्या वह बोनस मार्क C # के लिए मान्य है? मैंने सोचा नहीं होगा, जब तक कि MSIL की व्याख्या नहीं की जाती है, जब तक कि अभिव्यक्ति मशीन कोड के ठीक नीचे संकलित न हो।
जेरेमी मैकगी

7
@ जेरेमी एमएसआईएल की व्याख्या नहीं की गई है।
जोनाथन डिकिंसन

2
@ डीईडी उत्तर का उत्तर दें - मैंने इस बारे में एक एकालाप जोड़ा है कि आप इस बारे में क्यों चिंतित होंगे। और, FYI, (x && y)अनुवाद करता है, LOAD x; BRANCH_FALSE; LOAD y; BRANCH_FALSE;जहाँ (x & y)अनुवाद करता है LOAD x; LOAD y; AND; BRANCH_FALSE;। एक शाखा बनाम दो।
जोनाथन डिकिंसन

68

लॉजिकल ऑपरेटर ( ||और &&) बनाम बिटवाइज़ ऑपरेटर ( |और &)।

एक तार्किक ऑपरेटर और बिटवाइज़ ऑपरेटर के बीच सबसे महत्वपूर्ण अंतर यह है कि एक तार्किक ऑपरेटर दो बूलियन लेता है और एक बूलियन का उत्पादन करता है जबकि एक बिटवाइज़र ऑपरेटर दो पूर्णांक लेता है और एक पूर्णांक बनाता है (ध्यान दें: पूर्णांक का अर्थ है किसी भी अभिन्न डेटा प्रकार, न कि केवल इंट)।

पांडित्यपूर्ण होने के लिए, एक बिटवाइज़ ऑपरेटर एक बिट-पैटर्न (जैसे 01101011) लेता है और प्रत्येक बिट के लिए एक बिट-वार और / या करता है। उदाहरण के लिए, यदि आपके पास दो 8-बिट पूर्णांक हैं:

a     = 00110010 (in decimal:    32+16+2   = 50)
b     = 01010011 (in decimal: 64+   16+2+1 = 83)
----------------
a & b = 00010010 (in decimal:       16+2   = 18)
a | b = 01110011 (in decimal: 64+32+16+2+1 = 115)

जबकि एक तार्किक ऑपरेटर केवल इसमें काम करता है bool:

a      = true
b      = false
--------------
a && b = false
a || b = true

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

एक अन्य महत्वपूर्ण अंतर यह भी है कि एक तार्किक ऑपरेटर कम परिचालित होता है । इस प्रकार, कुछ मंडलियों में [1], आप अक्सर लोगों को कुछ ऐसा करते हुए देखते हैं:

if (person && person.punch()) {
    person.doVictoryDance()
}

जो अनुवाद करता है: "यदि व्यक्ति मौजूद है (अर्थात अशक्त नहीं है), तो उसे पंच करने की कोशिश करें, और यदि पंच सफल होता है (यानी सच लौटाता है), तो एक विजय नृत्य करें"

क्या आपने इसके बजाय बिटकॉइन ऑपरेटर का उपयोग किया था:

if (person & person.punch()) {
    person.doVictoryDance()
}

में अनुवाद होगा: "यदि व्यक्ति मौजूद है (अर्थात अशक्त नहीं है) और पंच सफल होता है (यानी सही रिटर्न देता है), तो एक विजय नृत्य करें"

ध्यान दें कि शॉर्ट-सर्कुलेटेड लॉजिकल ऑपरेटर में, person.punch()कोड personशून्य होने पर बिल्कुल भी नहीं चलाया जा सकता है। वास्तव में, इस विशेष मामले में, दूसरा कोड एक अशक्त संदर्भ त्रुटि पैदा करेगा यदि personअशक्त है, क्योंकि यह person.punch()किसी भी व्यक्ति को कॉल करने की कोशिश करता है चाहे वह अशक्त हो या नहीं। सही ऑपरेंड का मूल्यांकन नहीं करने के इस व्यवहार को शॉर्ट-सर्क्युटिंग कहा जाता है ।

[१] कुछ प्रोग्रामर एक फंक्शन कॉल लगाने के लिए बोलेंगे जो एक ifअभिव्यक्ति के अंदर एक साइड इफेक्ट है , जबकि अन्य के लिए यह एक सामान्य और बहुत उपयोगी मुहावरा है।

चूँकि एक बिटवाइज़ ऑपरेटर एक बार में 32-बिट्स पर काम करता है (यदि आप 32-बिट मशीन पर हैं), तो यह अधिक सुंदर और तेज़ कोड को जन्म दे सकता है, यदि आपको बहुत अधिक परिस्थितियों की तुलना करने की आवश्यकता है, जैसे।

int CAN_PUNCH = 1 << 0, CAN_KICK = 1 << 1, CAN_DRINK = 1 << 2, CAN_SIT = 1 << 3,
    CAN_SHOOT_GUNS = 1 << 4, CAN_TALK = 1 << 5, CAN_SHOOT_CANNONS = 1 << 6;

Person person;
person.abilities = CAN_PUNCH | CAN_KICK | CAN_DRINK | CAN_SIT | CAN_SHOOT_GUNS;

Place bar;
bar.rules = CAN_DRINK | CAN_SIT | CAN_TALK;

Place military;
military.rules = CAN_SHOOT_CANNONS | CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT;

CurrentLocation cloc1, cloc2;
cloc1.usable_abilities = person_abilities & bar_rules;
cloc2.usable_abilities = person_abilities & military_rules;

// cloc1.usable_abilities will contain the bit pattern that matches `CAN_DRINK | CAN_SIT`
// while cloc2.usable_abilities will contain the bit pattern that matches `CAN_PUNCH | CAN_KICK | CAN_SHOOT_GUNS | CAN_SIT`

तार्किक ऑपरेटरों के साथ ऐसा करने के लिए तुलना की अजीब मात्रा की आवश्यकता होगी:

Person person;
person.can_punch = person.can_kick = person.can_drink = person.can_sit = person.can_shoot_guns = true;
person.can_shoot_cannons = false;

Place bar;
bar.rules.can_drink = bar.rules.can_sit = bar.rules.can_talk = true;
bar.rules.can_punch = bar.rules.can_kick = bar.rules.can_shoot_guns = bar.rules.can_shoot_cannons = false;

Place military;
military.rules.can_punch = military.rules.can_kick = military.rules.can_shoot_guns = military.rules.can_shoot_cannons = military.rules.can_sit = true;
military.rules.can_drink = military.rules.can_talk = false;

CurrentLocation cloc1;
bool cloc1.usable_abilities.can_punch         = bar.rules.can_punch         && person.can_punch,
     cloc1.usable_abilities.can_kick          = bar.rules.can_kick          && person.can_kick,
     cloc1.usable_abilities.can_drink         = bar.rules.can_drink         && person.can_drink,
     cloc1.usable_abilities.can_sit           = bar.rules.can_sit           && person.can_sit,
     cloc1.usable_abilities.can_shoot_guns    = bar.rules.can_shoot_guns    && person.can_shoot_guns,
     cloc1.usable_abilities.can_shoot_cannons = bar.rules.can_shoot_cannons && person.can_shoot_cannons
     cloc1.usable_abilities.can_talk          = bar.rules.can_talk          && person.can_talk;

bool cloc2.usable_abilities.can_punch         = military.rules.can_punch         && person.can_punch,
     cloc2.usable_abilities.can_kick          = military.rules.can_kick          && person.can_kick,
     cloc2.usable_abilities.can_drink         = military.rules.can_drink         && person.can_drink,
     cloc2.usable_abilities.can_sit           = military.rules.can_sit           && person.can_sit,
     cloc2.usable_abilities.can_shoot_guns    = military.rules.can_shoot_guns    && person.can_shoot_guns,
     cloc2.usable_abilities.can_talk          = military.rules.can_talk          && person.can_talk,
     cloc2.usable_abilities.can_shoot_cannons = military.rules.can_shoot_cannons && person.can_shoot_cannons;

एक शास्त्रीय उदाहरण जहां बिट-पैटर्न और बिटवाइज़ ऑपरेटर का उपयोग किया जाता है, वह यूनिक्स / लिनक्स फ़ाइल सिस्टम अनुमतियों में है।


3
पक्ष के लिए +1 समस्या को प्रभावित करता है। आश्चर्य की बात यह पहले उल्लेख नहीं किया गया था
कॉनराड फ्रैक्स

3
उदाहरण थोड़ा हिंसक लगता है, लेकिन लगता है कि अन्य उत्तर शॉर्ट सर्किटिंग पर बहुत अधिक ध्यान केंद्रित करते हैं और पूर्णांकों पर और बूलियंस पर काम करने के बीच के अंतर पर पर्याप्त नहीं हैं।
R0MANARMY

कार्यान्वयन विवरण (शॉर्ट-सर्टिक्ट / साइड इफेक्ट्स) को खेलने से पहले फंक्शन को समझना चाहिए। ख़ुशी है कि आपने मुख्य अंतर को बूलियन बनाम पूर्णांक तर्क के रूप में साफ़ किया, न कि लघु-परिच्छेद के रूप में।
हाबिल

@ कृषि - हिंसक, मुझे आपके साधु को दी गई विडंबना से प्यार है। अच्छा काम
brumScouse 15

8

के मामले में:

if (obj != null && obj.Property == true) { }

उम्मीद के मुताबिक काम करेंगे।

परंतु:

if (obj != null & obj.Property == true) { }

संभावित रूप से एक शून्य संदर्भ अपवाद फेंक सकता है।


2

लघु और सरल:

1 && 2= true
क्योंकि
C में
1 = true (नॉन-जीरो) C में = true (नॉन-जीरो)

trueANDS तार्किक रूप trueसे देने के लिए true

परंतु

1 & 2= 0 = झूठा
क्योंकि
बाइनरी में 1 = 0001 बाइनरी में
2 = 0010

0001 के साथ 0001 ANDs बिटवाइज 0000 = 0 दशमलव में देने के लिए।

इसी तरह के लिए || और | ऑपरेटरों को भी ...!


2
-1: हम सी # के बारे में बात कर रहे हैं ... 1 && 2सी # में अवैध है
डैनियल हिल्गरथ

लेकिन यह एक अत्यंत महत्वपूर्ण उदाहरण है जो बताता है कि आप केवल & && (जो कि बहुत से लोगों को लगता है) को इंटरचेंज नहीं कर सकते हैं
bobobobo

1

&&का शॉर्ट सर्किट संस्करण है &

यदि हम मूल्यांकन कर रहे हैं false & true, तो हम पहले से ही पहले तर्क को देखने से जानते हैं कि परिणाम गलत होगा। &&ऑपरेटर का संस्करण पूरी अभिव्यक्ति का मूल्यांकन करने के बजाय जल्द से जल्द एक परिणाम देगा। वहाँ भी की एक ऐसी ही verion है |, ऑपरेटर ||


1
if (list.Count() > 14 && list[14] == "foo")

सुरक्षित है

if (list.Count() > 14 & list[14] == "foo")

यदि सूची में सही आकार नहीं है तो दुर्घटना होगी।


मैं कल्पना नहीं कर सकता कि कोई व्यक्ति "if (list.Count ()> 14 और सूची [14] ==" foo ") को" if (list.Count) ()> 14 && सूची [14] == "के बजाय लिख सकता है foo ")"। & सिर्फ और स्वाभाविक रूप से इस मामले में && का उपयोग नहीं किया जा सकता है, भले ही वह निश्चित रूप से सुरक्षित हो (सूची [1] उदाहरण के लिए)।
टीएन डू

1

सी # ऑपरेटरों को यह बताना चाहिए कि:

अनिवार्य रूप से दो &का होना या |इसका मतलब है कि यह एक तार्किक के बजाय एक सशर्त है, इसलिए आप दोनों के बीच अंतर बता सकते हैं।

& ऑपरेटर का उपयोग करने का एक उदाहरण है&


दोनों लिंक (प्रभावी रूप से) टूटे हुए हैं ( "Visual Studio 2005 सेवानिवृत्त प्रलेखन" पर पुनर्निर्देशित )।
पीटर मोर्टेंसन

1

ठीक है, अंकित मूल्य पर

    Boolean a = true;
    Boolean b = false;

    Console.WriteLine("a({0}) && b({1}) =  {2}", a, b, a && b);
    Console.WriteLine("a({0}) || b({1}) =  {2}", a, b, a || b);
    Console.WriteLine("a({0}) == b({1}) =  {2}", a, b, a == b);

    Console.WriteLine("a({0}) & b({1}) =  {2}", a, b, a & b);
    Console.WriteLine("a({0}) | b({1}) =  {2}", a, b, a | b);
    Console.WriteLine("a({0}) = b({1}) =  {2}", a, b, a = b);

उसी उत्तर का उत्पादन करें। हालाँकि, जैसा कि आपने दिखाया, यदि आपके पास अधिक जटिल प्रश्न है:

if (a and b and c and d) ..

अगर aयह सच नहीं है और हो सकता bहै कि यह एक ऐसा समारोह है जहाँ इसे बंद करना है, कुछ से कनेक्ट करना है, इसे प्राप्त करें, ऐसा करें, निर्णय लें .. परेशान क्यों हों? समय की बर्बादी, आप जानते हैं कि यह पहले से ही विफल है। मशीन बंद क्यों करें और अतिरिक्त व्यर्थ काम करें?

मैंने हमेशा उपयोग किया है &&क्योंकि मैंने सबसे पहले असफल होने की संभावना रखी है, जब कोई बात नहीं है, तो आगे बढ़ने से पहले कम गणना करें। यदि आपके पास कम संभावना वाले विकल्पों की भविष्यवाणी करने का कोई तरीका नहीं है, जैसे कि आपके पास डेटा का आउटपुट सीमित करने के लिए एक बूलियन है, तो कुछ इस तरह:

if (limit && !MyDictionary.ContainsKey("name")) 
    continue;

यदि यह नहीं है limit, तो कुंजी के लिए जाँच को परेशान न करें, जो अधिक समय ले सकता है।


1

जब एक तार्किक अभिव्यक्ति में प्रयोग किया जाता है जैसे कि यदि कोई कथन &&बेहतर हो क्योंकि यह पहला गलत परिणाम सामने आते ही अभिव्यक्तियों का मूल्यांकन करना बंद कर देगा। यह संभव है क्योंकि एक गलत मूल्य पूरे अभिव्यक्ति को गलत होने का कारण होगा। इसी तरह और फिर से तार्किक अभिव्यक्तियों में) ||बेहतर है क्योंकि यह अभिव्यक्ति का मूल्यांकन करना बंद कर देगा क्योंकि यह एक वास्तविक अभिव्यक्ति का सामना करता है क्योंकि किसी भी वास्तविक मूल्य के कारण पूरी अभिव्यक्ति सच हो जाएगी।

यदि हालाँकि अभिव्यक्तियों या साथ-साथ या एड-एड का एक साथ साइड इफेक्ट होता है, और आप चाहते हैं कि ये सब आपकी अभिव्यक्ति (तार्किक अभिव्यक्ति के परिणाम की परवाह किए बिना) के परिणामस्वरूप हो , तब &और |इसका उपयोग किया जा सकता है। इसके विपरीत, &&और ||ऑपरेटर अवांछित साइड-इफेक्ट्स के खिलाफ गार्ड के रूप में उपयोगी हो सकते हैं (जैसे कि एक शून्य सूचक एक अपवाद के रूप में फेंका जा सकता है)।

&और |ऑपरेटर भी पूर्णांकों के साथ इस्तेमाल किया जा सकता है और इस मामले में वे एक पूर्णांक जिसके परिणामस्वरूप दो ऑपरेंड और एड या है या-एड बिट स्तर पर एक साथ पैदा करते हैं। यह तब उपयोगी हो सकता है जब पूर्णांक मान के बाइनरी बिट्स को सही और गलत मानों की एक सरणी के रूप में उपयोग किया जाता है। यह जांचने के लिए कि एक निश्चित बिट चालू है या बंद है, एक बिट-मास्क बिटवाइज़ है और वैल्यू के साथ एड है। थोड़ा चालू करने के लिए, मूल्य के साथ एक ही मुखौटा बिटवाइज़ या एड हो सकता है। अंत में थोड़ा बंद करने के लिए, ~मूल्य के साथ एक मुखौटा का बिटवाइज़ पूरक (उपयोग ) बिटवाइज़ और एड है।

int a = 0; // 0 means all bits off
a = a | 4; // set a to binary 100
if ((a & 4) != 0) {
    // will do something
}
a = a & (~4) // turn bit off again, a is now 000

C # के अलावा अन्य भाषाओं में, लॉजिकल व बिटवाइज़ मोड और; ऊपर दिए गए कोड में, ifबयान की सशर्त अभिव्यक्ति (a & 4) != 0इस स्थिति को व्यक्त करने का एक सुरक्षित तरीका है, लेकिन कई सी भाषाओं की तरह, सशर्त कथन केवल शून्य पूर्णांक मानों को गलत और शून्य-शून्य पूर्णांक मानों को सही मान सकते हैं। (इसका कारण उपलब्ध सशर्त शाखा प्रोसेसर निर्देशों से संबंधित है, और पूर्णांक ऑपरेशन के बाद अद्यतन किए गए शून्य ध्वज से उनका संबंध है।) इसलिए ìfशून्य के लिए कथन का परीक्षण हटाया जा सकता है और स्थिति को छोटा किया जा सकता है (a & 4)

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

if (foo() & bar()) {
    // do something
}

C में, यदि foo()रिटर्न 1 और bar()रिटर्न 2 है, तो "कुछ" 1 & 2शून्य नहीं होगा ।

सी # के लिए ifबूलियन ऑप्रेंड की तरह सशर्त बयान की आवश्यकता होती है , और भाषा एक पूर्णांक मान को बूलियन मान में डालने की अनुमति नहीं देती है। तो ऊपर कोड संकलक त्रुटियों को उत्पन्न करेगा। यह अधिक सही ढंग से इस प्रकार व्यक्त किया जाएगा:

if (foo() != 0 & bar() != 0) {
    // do something
}

1

यदि आप एक पुराने टाइमर सी प्रोग्रामर हैं, तो सावधान रहें । सी # ने मुझे वाकई चौंका दिया है।

MSDN| ऑपरेटर के लिए कहता है :

बाइनरी | ऑपरेटर अभिन्न प्रकार और बूल के लिए पूर्वनिर्धारित हैं । अभिन्न प्रकार के लिए, | बिटकॉइन या उसके ऑपरेंड की गणना करता है। बूल ऑपरेंड के लिए, | अपने परिचालनों के तार्किक OR की गणना करता है; यही कारण है कि, परिणाम गलत है अगर और केवल अगर उसके दोनों ऑपरेंड झूठे हैं।

(जोर मेरा है।) बूलियन प्रकार को विशेष रूप से संभाला जाता है, और इस संदर्भ में सवाल केवल समझ में आने लगता है, और अंतर यह है, क्योंकि अन्य पहले से ही उनके जवाब में निष्कासित हैं:

&&और ||शॉर्ट-सर्किटिंग हैं। &और दोनों ऑपरेंड का |मूल्यांकन करें ।

और जो बेहतर है, वह साइड-इफेक्ट्स, प्रदर्शन और कोड पठनीयता जैसी कई चीजों पर निर्भर करता है, लेकिन आमतौर पर शॉर्ट-सर्कुलेटिंग ऑपरेटर बेहतर होते हैं, क्योंकि वे मेरे जैसे समान पृष्ठभूमि वाले लोगों द्वारा बेहतर समझे जाते हैं।

कारण यह है: मैं इस तरह से बहस करूंगा: चूंकि सी में कोई वास्तविक बूलियन प्रकार नहीं है, आप बिटवाइज़ ऑपरेटर का उपयोग कर सकते हैं |और इसके परिणाम का मूल्यांकन सत्य या गलत स्थिति में किया जा सकता है। लेकिन यह सी # के लिए गलत रवैया है, क्योंकि पहले से ही बूलियन प्रकार के लिए एक विशेष मामला है।


0

यह महत्वपूर्ण है, क्योंकि अगर bool2 (उदाहरण के लिए) के मूल्यांकन की लागत अधिक है, लेकिन bool1 गलत है, तो आपने && ओवर & का उपयोग करके अपने आप को गणना का एक अच्छा हिस्सा बचा लिया है


0

क्योंकि &&और जैसे प्रवाह नियंत्रण के|| लिए उपयोग किया जाता है वैसे ही हैं। यह हमेशा सशर्त के बारे में नहीं है। यह एक बयान के रूप में लिखना पूरी तरह से उचित है , न कि एक शर्त के रूप में, निम्नलिखित:if/elseifwhile

 a() && b() && c() && d();

या और भी

 w() || x() || y() || z();

यह सिर्फ इतना ही नहीं है कि यह समकक्ष if/elseसंस्करणों की तुलना में टाइप करना आसान है ; वे पढ़ने और समझने में भी बहुत आसान हैं।


0

&& और & का मतलब दो बहुत अलग चीजें हैं और आपको दो अलग-अलग उत्तर देते हैं।

1 && 2पैदावार 1 ("सच")
1 & 2पैदावार 0 ("झूठी")

&&एक तर्क ऑपरेटर है - इसका मतलब है "सच है अगर दोनों ऑपरेंड सच हैं"
&एक बिटवाइज़ तुलना है। इसका मतलब है "मुझे बताओ कि दोनों ऑपरेंड्स में कौन से बिट सेट हैं"


2
सवाल # सी के बारे में है। C # में, एक बूल को नंबर देने का कोई तरीका नहीं है, इसलिए 0 'झूठी' नहीं है और नॉनज़रो 'सच नहीं है'; बस कोई तुल्यता नहीं है।
नैट सीके

संख्या को बूल में परिवर्तित करने के लिए, इस तरह से कि 1 का अर्थ है सच और 0 का अर्थ है झूठ, "n! = 0" (मुझे लगता है ... मैं वास्तव में C # से परिचित नहीं हूं)। वास्तव में मैं इस टिप्पणी को वापस लेना चाहता था क्योंकि यह अच्छी तरह से शोध नहीं है और मुझे नहीं लगता कि यह पिछली टिप्पणी के लिए अब उपयोगी या वास्तव में प्रासंगिक है कि मैं इसके बारे में अधिक सोचता हूं, लेकिन मैं गलती से प्रवेश कर गया और अब मुझे नहीं लगता कि मैं कर सकता हूं इसे यहाँ रद्द करें, फिर जाने के लिए, जो भी इसके लायक है :-)
डॉन हैच

1 && 2एक संकलक त्रुटि देता है: "त्रुटि 4 ऑपरेटर 'और&' को 'int' और 'int' प्रकार के ऑपरेंड पर लागू नहीं किया जा सकता है
पीटर मॉर्टेंसन

0

यह करने वाले लोगों को यह समझाने के लिए सबसे तेज (और थोड़ा नीचे दबाना) तरीका है कि ऐसा करने वाले कोड के सटीक संचालन को जानने के लिए जरूरी नहीं है

&& उन स्थितियों में से प्रत्येक पर एक जाँच कर रहा है जब तक कि वह एक झूठी नहीं मिलती है और पूरे परिणाम को गलत के रूप में वापस करती है

|| उन स्थितियों में से प्रत्येक पर एक जाँच कर रहा है जब तक कि वह एक सत्य नहीं पाता है और पूरे परिणाम को सत्य के रूप में लौटाता है।

& MATHS आधारित एपन BOTH / सभी शर्तों पर काम कर रहा है और परिणाम से निपट रहा है।

| MATHS आधारित एपन BOTH / सभी स्थितियों को कर रहा है और परिणाम के साथ काम कर रहा है।

मैं एक बिंदु है जहां मैं का उपयोग करने के लिए आवश्यक है भर में कभी नहीं आए हैं और या | एक if स्टेटमेंट के भीतर। मैं ज्यादातर हेक्साडेसिमल मानों को बिटविन शिफ्ट का उपयोग करके अपने घटक रंगों में काटने के लिए उपयोग करता हूं।

ईजी:

r = fullvalue >> 0xFF & 0xFF;
g = fullvalue >> 0xF & 0xFF;
b = fullvalue & 0xFF;

इस ऑपरेशन के भीतर "& 0xFF" केवल द्विआधारी मूल्य को देखने के लिए मजबूर कर रहा है। मुझे व्यक्तिगत रूप से इसके लिए उपयोग नहीं मिला है | हालाँकि अभी तक।


0

सीधे शब्दों में,

if exp1 && exp2

अगर exp1 की flase जाँच exp2 नहीं है

परंतु

if exp1 & exp2

अगर exp1 है falseया true exp2 चेक करें

और शायद ही कभी लोग उपयोग करते हैं &क्योंकि वे exp1 की जांच करना चाहते हैंfalse

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.