सी # तर्क आदेश और संकलक व्यवहार

सी # में, (और अन्य भाषाओं के लिए उत्तर देने में संकोच न करें), रनटाइम तर्क तर्क का मूल्यांकन किस क्रम में करता है?

उदाहरण:

DataTable myDt = new DataTable();
if (myDt != null && myDt.Rows.Count > 0)
{
    //do some stuff with myDt
}

रनटाइम का पहला कथन पहले मूल्यांकन करता है -

myDt != null

या:

myDt.Rows.Count > 0

?

क्या ऐसा समय है जब संकलक कभी कथन का मूल्यांकन करेगा? शायद जब एक "OR" ऑपरेटर शामिल है?


& is known as a logical bitwise operator and will always evaluate all the sub-expressions

"शॉर्ट-सर्किट बूलियन" के बजाय बिटवाई ऑपरेटर का उपयोग करने का एक अच्छा उदाहरण क्या है?

0
ro fr bn

18 उत्तर

मुझे ओरियन के जवाब पसंद हैं। मैं दो चीजें जोड़ूंगा:

  1. बाएं से दाएं अभी भी पहले
  2. लागू होता है
  3. कार्य को कॉल करने से पहले सभी तर्कों को हल करने के लिए आंतरिक-से-बाहरी

मान लें कि हमारे पास निम्न उदाहरण है:

a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
           GetSummary("Chris", GetAddress("Chris")));

निष्पादन का आदेश यहां दिया गया है:

  1. GetAddress("Orion")
  2. GetSummary("Orion", ...)
  3. GetAddress("Chris")
  4. GetSummary("Chris", ...)
  5. Foo(...)
  6. Assigns to a

मैं सी # की कानूनी आवश्यकताओं के बारे में बात नहीं कर सकता (हालांकि मैंने इस पोस्ट को लिखने से पहले मोनो का उपयोग करके एक समान उदाहरण का परीक्षण किया था), लेकिन जावा में यह ऑर्डर गारंटी है।

And just for completeness (since this is a language-agnostic thread as well), there are languages like C and C++, where the order is not guaranteed unless there is a sequence point. References: 1, 2. In answering the thread's question, however, && and || are sequence points in C++ (unless overloaded; also see OJ's excellent answer). So some examples:

  • foo() && bar()
  • foo() & bar()

In the && case, foo() is guaranteed to run before bar() (if the latter is run at all), since && is a sequence point. In the & case, no such guarantee is made (in C and C++), and indeed bar() can run before foo(), or vice versa.

0
जोड़ा

बाएं एक, फिर बंद हो जाता है अगर यह शून्य है।

संपादित करें: vb.net में यह दोनों का मूल्यांकन करेगा और संभवतः एक त्रुटि फेंक देगा, जब तक कि आप AndAlso का उपयोग न करें

0
जोड़ा

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

तर्क में अभिव्यक्ति बाएं से दाएं रहेंगी, लेकिन उदाहरण के लिए:

puts message unless message.nil?

उपर्युक्त "message.nil" का मूल्यांकन करेगा? सबसे पहले, यदि यह झूठे का मूल्यांकन करता है (जब तक कि यह सत्य की बजाय स्थिति गलत होने पर इसे निष्पादित करने के बावजूद), "संदेश डालता है" निष्पादित करेगा, जो संदेश चर के स्क्रीन को सामग्री में प्रिंट करता है।

यह कभी-कभी आपके कोड को ढूढ़ने का एक दिलचस्प तरीका है ... मैं व्यक्तिगत रूप से इसे उपरोक्त की तरह बहुत कम 1 लाइनर के लिए उपयोग करना पसंद करता हूं।

संपादित करें:

इसे थोड़ा स्पष्ट बनाने के लिए, उपर्युक्त जैसा ही है:

unless message.nil?
  puts message
end
0
जोड़ा

@shsteimer

अवधारणा विनम्रता ऑपरेटर ओवरलोडिंग का जिक्र कर रही है। बयान में:   ...   ए का मूल्यांकन पहले किया जाता है, अगर यह झूठे मूल्यांकन करता है, बी का मूल्यांकन कभी नहीं किया जाता है। वही

पर लागू होता है

यह ऑपरेटर ओवरलोडिंग नहीं है। ऑपरेटर ओवरलोडिंग आपको ऑपरेटर के लिए कस्टम व्यवहार को परिभाषित करने के लिए दिया गया शब्द है, जैसे *, +, = और इसी तरह।

यह आपको अपनी 'लॉग' कक्षा लिखने देगा, और फिर करें

a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.

यह कर रहा हूं

a() || b() // be never runs if a is true

is actually called Short Circuit Evaluation

0
जोड़ा

जब चीजें सभी ऑनलाइन होती हैं, तो उन्हें बाएं से दाएं निष्पादित किया जाता है।

जब चीजें घोंसले की जाती हैं, तो उन्हें आंतरिक-से-बाहरी निष्पादित किया जाता है। यह आमतौर पर उलझन में प्रतीत होता है क्योंकि रेखा के दाईं ओर "आंतरिक" क्या होता है, ऐसा लगता है कि यह पीछे की तरफ जा रहा है ...

उदाहरण के लिए

a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );

चीजें इस तरह होती हैं:

  • Call GetAddress with the literal "Orion"
  • Call GetSummary with the literal "Orion" and the result of GetAddress
  • Call Foo with the literal 5 and the result of GetSummary
  • Assign this value to a
0
जोड़ा

अवधारणा विनम्रता ऑपरेटर ओवरलोडिंग का जिक्र कर रही है। बयान में:

if( A && B){
    // do something
}

ए का मूल्यांकन पहले किया जाता है, अगर यह झूठे मूल्यांकन करता है, बी का मूल्यांकन कभी नहीं किया जाता है। वही लागू होता है

if(A || B){
    //do something
}

ए का मूल्यांकन पहले किया जाता है, यदि यह सत्य का मूल्यांकन करता है, बी का मूल्यांकन कभी नहीं किया जाता है।

यह अवधारणा, अधिभार, (सी सोचती है) सभी सी शैली भाषाओं, और कई अन्य लोगों पर भी लागू होती है।

0
जोड़ा

vb.net

if( x isNot Nothing AndAlso x.go()) then
  1. Evaluation is done left to right
  2. AndAlso operator makes sure that only if the left side was TRUE, the right side will be evaluated (very important, since ifx is nothing x.go will crash)

आप vb में और भी इसके बजाय और का उपयोग कर सकते हैं। जिस स्थिति में बाएं पक्ष का मूल्यांकन पहले भी किया जाता है, लेकिन परिणाम के बावजूद दाएं तरफ मूल्यांकन किया जाएगा।

बेस्ट प्रैक्टिस: हमेशा एंडलसो का उपयोग करें, जब तक कि आपके पास बहुत अच्छा कारण न हो।


It was asked in a followup why or when would anyone use And instead of AndAlso (or & instead of &&): Here is an example:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

इस मामले में, मैं वाई और वाई दोनों को इनिट करना चाहता हूं वाई वाईडेंस को निष्पादित करने में सक्षम होना चाहिए। हालांकि, init() फ़ंक्शन में मैं कुछ अतिरिक्त चीज भी कर रहा हूं जैसे सॉकेट की जांच करना खुला है, और केवल अगर यह ठीक काम करता है, तो दोनों के लिए, मुझे आगे बढ़ना चाहिए और x.process करना चाहिए (y)।

फिर, शायद 99% मामलों में इसकी आवश्यकता नहीं है और सुरुचिपूर्ण नहीं है, इसलिए मैंने कहा कि डिफ़ॉल्ट और इसके अलावा का उपयोग करना चाहिए।

0
जोड़ा

मैंने कहीं सुना है कि कंपाइलर्स पीछे की ओर काम करते हैं, लेकिन मुझे यकीन नहीं है कि यह कितना सच है।

0
जोड़ा

"शॉर्ट-सर्किट बूलियन" के बजाय बिटवाई ऑपरेटर का उपयोग करने का एक अच्छा उदाहरण क्या है?

मान लें कि आपके पास झंडे हैं, फ़ाइल विशेषताओं के लिए कहें। मान लीजिए कि आपने रीड को 4 के रूप में परिभाषित किया है, 2 के रूप में लिखें, और EXEC के रूप में 1. बाइनरी में, यह है:

READ  0100  
WRITE 0010  
EXEC  0001

प्रत्येक ध्वज में एक बिट सेट होता है, और प्रत्येक अद्वितीय है। बिटवाई ऑपरेटर आपको इन झंडे को गठबंधन करने देते हैं:

flags = READ & EXEC; // value of flags is 0101
0
जोड़ा

ZombieSheep is dead-on. The only "gotcha" that might be waiting is that this is only true if you are using the && operator. When using the & operator, both expressions will be evaluated every time, regardless if one or both evaluate to false.

if (amHungry & whiteCastleIsNearby)
{
   // The code will check if White Castle is nearby
   // even when I am not hungry
}

if (amHungry && whiteCastleIsNearby)
{
   // The code will only check if White Castle is nearby
   // when I am hungry
}
0
जोड़ा

Nopes, at least the C# compiler doesn't work backwards (in either && or ||). It's left to right.

0
जोड़ा

सी #: बाएं से दाएं, और यदि गैर-मिलान (झूठ का मूल्यांकन) पाया जाता है तो प्रसंस्करण बंद हो जाता है।

0
जोड़ा
जैसा कि अन्य ने कहा है, & & ऑपरेटर पर शॉर्ट-सर्किटिंग false पर होती है।
जोड़ा लेखक Broam, स्रोत

The D programming language Does do left-to-right evaluation with short circuiting and doesn't allow overloading of the && and '||' operators.

0
जोड़ा

You use & when you specifically want to evaluate all the sub-expressions, most likely because they have side-effects you want, even though the final result will be false and thus not execute your then part of your if-statement.

Note that & and | operates for both bitwise masks and boolean values and is not just for bitwise operations. They're called bitwise, but they are defined for both integers and boolean data types in C#.

0
जोड़ा

Note that there is a difference between && and & regarding how much of your expression is evaluated.

&& is known as a short-circuited boolean AND, and will, as noted by others here, stop early if the result can be determined before all the sub-expressions are evaluated.

& is known as a logical bitwise operator and will always evaluate all the sub-expressions.

जैसे की:

if (a() && b())

अगर a true लौटाता है तो केवल b को कॉल करेगा।

हालांकि, यह:

if (a() & b())

हमेशा a और b दोनों को कॉल करेंगे, भले ही a को कॉल करने का नतीजा गलत है और इस प्रकार false b को कॉल करने के परिणाम के बावजूद।

यह वही अंतर || के लिए मौजूद है और | ऑपरेटरों।

0
जोड़ा

"सी #: बाएं से दाएं, और प्रसंस्करण बंद हो जाता है यदि एक मैच (सत्य का मूल्यांकन) पाया जाता है।"

ज़ोंबी भेड़ गलत है, इसे वोट करने के लिए पर्याप्त प्रतिनिधि नहीं है।

The question is about the && operator, not the || operator.

In the case of && evaluation will stop if a FALSE is found.

|| के मामले में यदि कोई सत्य पाया जाता है तो मूल्यांकन बंद हो जाता है।

0
जोड़ा
हां। आप बिल्कुल सही हैं। मुझे आशा है कि मेरा मूल उत्तर सही तरीके से व्याख्या किया गया था, हालांकि। यह निश्चित रूप से किसी को भी गुमराह करने का मेरा इरादा नहीं था।
जोड़ा लेखक ZombieSheep, स्रोत

@csmba:

It was asked in a followup why or when would anyone use And instead of AndAlso (or & instead of &&): Here is an example:

if ( x.init() And y.init()) then
   x.process(y)
end 
y.doDance()

In this case, I want to init both X and Y. Y must be initialized in order for y.DoDance to be able to execute. However, in the init() function I am doing also some extra thing like checking a socket is open, and only if that works out ok, for both, I should go ahead and do the x.process(y).

I believe this is rather confusing. Although your example works, it's not the typical case for using And (and I would probably write this differently to make it clearer). And (& in most other languages) is actually the bitwise-and operation. You would use it to calculate bit operations, for example deleting a flag bit or masking and testing flags:

Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
    MsgBox("The text will be set in italic.")
End If
0
जोड़ा

मुझे एहसास है कि इस प्रश्न का उत्तर पहले से ही दिया जा चुका है, लेकिन मैं इस विषय से संबंधित कुछ अन्य जानकारी में फेंकना चाहता हूं।

In languages, like C++, where you can actually overload the behaviour of the && and || operators, it is highly recommended that you do not do this. This is because when you overload this behaviour, you end up forcing the evaluation of both sides of the operation. This does two things:

  1. यह आलसी मूल्यांकन तंत्र को तोड़ता है क्योंकि ओवरलोड एक ऐसा फ़ंक्शन है जिसे लागू किया जाना चाहिए, और इसलिए फ़ंक्शन को कॉल करने से पहले दोनों पैरामीटर का मूल्यांकन किया जाता है।
  2. कहा पैरामीटर के मूल्यांकन का आदेश गारंटी नहीं है और संकलक विशिष्ट हो सकता है। इसलिए ऑब्जेक्ट्स वैसे ही व्यवहार नहीं करेंगे जैसा वे प्रश्न / पिछले उत्तरों में सूचीबद्ध उदाहरणों में करते हैं।

अधिक जानकारी के लिए, स्कॉट मेयर्स की पुस्तक, अधिक प्रभावी C ++ का एक पठन पढ़ें। चीयर्स!

0
जोड़ा