जावा लॉजिकल ऑपरेटर शॉर्ट-सर्किटिंग


100

कौन सा सेट शॉर्ट-सर्कुलेटिंग है, और वास्तव में इसका क्या मतलब है कि जटिल सशर्त अभिव्यक्ति शॉर्ट-सर्किटिंग है?

public static void main(String[] args) {
  int x, y, z;

  x = 10;
  y = 20;
  z = 30;

  // T T
  // T F
  // F T
  // F F

  //SET A
  boolean a = (x < z) && (x == x);
  boolean b = (x < z) && (x == z);
  boolean c = (x == z) && (x < z);
  boolean d = (x == z) && (x > z);
  //SET B    
  boolean aa = (x < z) & (x == x);
  boolean bb = (x < z) & (x == z);
  boolean cc = (x == z) & (x < z);
  boolean dd = (x == z) & (x > z);

}

4
इस प्रश्न को देखें: stackoverflow.com/questions/7101992/…
Eng.Fouad

जवाबों:


244

&&और ||ऑपरेटरों "शॉर्ट सर्किट", जिसका अर्थ है कि वे दाएँ हाथ की ओर का मूल्यांकन नहीं है, तो यह आवश्यक नहीं है।

&और |ऑपरेटरों, जब तार्किक ऑपरेटर के रूप में प्रयोग किया जाता है, हमेशा के लिए दोनों पक्षों का मूल्यांकन।

प्रत्येक ऑपरेटर के लिए शॉर्ट-सर्किटिंग का केवल एक ही मामला है, और वे हैं:

  • false && ...- यह जानना जरूरी नहीं है कि दाएं हाथ क्या है क्योंकि इसका परिणाम केवल falseमूल्य की परवाह किए बिना हो सकता है
  • true || ...- यह जानना जरूरी नहीं है कि दाएं हाथ क्या है क्योंकि इसका परिणाम केवल trueमूल्य की परवाह किए बिना हो सकता है

आइए एक सरल उदाहरण में व्यवहार की तुलना करें:

public boolean longerThan(String input, int length) {
    return input != null && input.length() > length;
}

public boolean longerThan(String input, int length) {
    return input != null & input.length() > length;
}

दूसरा संस्करण नॉन-शॉर्ट-सर्कुलेटिंग ऑपरेटर का उपयोग करता है &और NullPointerExceptionयदि inputहै तो उसे फेंक देगा null, लेकिन 1 संस्करण falseबिना किसी अपवाद के वापस आ जाएगा ।


9
मैं इस उत्तर को थोड़ा विस्तार देना चाहूंगा। & = ऑपरेटर एक्स = एक्स और अभिव्यक्ति के लिए एक शॉर्टहैंड है, और इसलिए शॉर्ट सर्किट नहीं है। वही | = = ऑपरेटर के बारे में सच है।
स्ट्रोमक्लाउड

11
एक बात मैं उजागर करना चाहूंगा, | और बाइनरी ऑपरेटर हैं, जबकि && और || सशर्त (तार्किक) ऑपरेटर हैं। | और & सिर्फ बूलियन से अधिक पर काम करते हैं, जबकि && और || केवल बूलियन पर काम करें।
एक मिथक

1
इतना ही नहीं वे दाहिने हाथ की ओर अभिव्यक्ति का मूल्यांकन नहीं करते हैं, मूल्यांकन के लिए कुछ भी होने के लिए कोड निष्पादित नहीं किया जाता है। यह समझने का एक महत्वपूर्ण बिंदु है कि क्या साइड इफेक्ट अन्यथा उत्पादन किया जाएगा।
mckenzm

@mckenzm मूल्यांकन और निष्पादित के बीच क्या अंतर है?
क्रोनेन

@ क्रोन एक्ज़ीक्यूशन मूल्यांकन से अधिक हो सकता है, और एक साइड इफेक्ट का उत्पादन कर सकता है, जैसे कि अपवाद या देरी, मैं इस उदाहरण के लिए प्रासंगिक नहीं हूं।
mckenzm

9

SET A शॉर्ट-सर्कुलेटिंग बूलियन ऑपरेटरों का उपयोग करता है।

बूलियन ऑपरेटर्स के संदर्भ में 'शॉर्ट-सर्कुलेटिंग' का मतलब यह है कि बुलियन बी 1, बी 2, ..., बीएन के एक सेट के लिए, इन बूलियंस के पहले जैसे ही शॉर्ट सर्किट संस्करणों का मूल्यांकन बंद हो जाएगा? ) या झूठी (&&)।

उदाहरण के लिए:

// 2 == 2 will never get evaluated because it is already clear from evaluating
// 1 != 1 that the result will be false.
(1 != 1) && (2 == 2)

// 2 != 2 will never get evaluated because it is already clear from evaluating
// 1 == 1 that the result will be true.
(1 == 1) || (2 != 2)

कृपया निर्दिष्ट करें कि यह मामला है &&, ||अलग तरीके से काम करता है और पहले ऑपरेंड पर मूल्यांकन को बंद कर देगा जो सच है;)
fge

1
वास्तव में, वास्तव में पूरा करने के लिए सभी को &&, ||, &और |बाएं से दाएं मूल्यांकन। बुलियन बी 1, बी 2, ..., बीएन के एक सेट के लिए, शॉर्ट सर्किट संस्करणों का मूल्यांकन बंद हो जाएगा जब इनमें से पहला सच है ( ||) या गलत ( &&)। बाह, सिद्धांत है;)
15

@fge: हां, आप बिल्कुल सही हैं। आपकी परिभाषा मेरी तुलना में अधिक सटीक है। मैंने आपकी टिप्पणी में वाक्य के साथ अपना उत्तर अपडेट कर दिया है। मुझे आशा है कि आप बुरा नहीं मानेंगे
afrischke

कोई चिंता नहीं, ज्ञान का कोई मूल्य नहीं है अगर इसे साझा नहीं किया जाता है।
फेज

4

शॉर्ट सर्कुलेटिंग का अर्थ है कि यदि दूसरा ऑपरेटर अंतिम परिणाम तय करता है तो दूसरे ऑपरेटर की जांच नहीं की जाएगी।

एग एक्सप्रेशन है: ट्रू || असत्य

के मामले में, हम सभी की जरूरत है एक तरफ से सच है इसलिए यदि बाएं हाथ की तरफ का हिस्सा सही है, तो दाहिने हाथ की तरफ जांचने का कोई मतलब नहीं है, और इसलिए इसे बिल्कुल भी चेक नहीं किया जाएगा।

इसी प्रकार, गलत और सत्य

&& के मामले में, हमें दोनों पक्षों के सच्चे होने की आवश्यकता है । इसलिए यदि बाएं हाथ की तरफ गलत है, तो दाहिने हाथ की तरफ जांचने का कोई मतलब नहीं है, जवाब गलत होना चाहिए। और इसीलिए इसकी जाँच बिल्कुल नहीं होगी।


4
boolean a = (x < z) && (x == x);

इस तरह का शॉर्ट-सर्किट होगा, जिसका अर्थ है कि यदि (x < z)गलत का मूल्यांकन किया जाता है तो बाद का मूल्यांकन नहीं किया जाता है, aयह गलत &&होगा , अन्यथा मूल्यांकन भी होगा (x == x)

& एक बिटवाइज़र ऑपरेटर है, लेकिन एक बूलियन और ऑपरेटर भी है जो शॉर्ट-सर्किट नहीं करता है।

आप उन्हें कुछ इस प्रकार से देख सकते हैं (देखें कि प्रत्येक मामले में विधि को कितनी बार कहा जाता है):

public static boolean getFalse() {
    System.out.println("Method");
    return false;
}

public static void main(String[] args) {
    if(getFalse() && getFalse()) { }        
    System.out.println("=============================");        
    if(getFalse() & getFalse()) { }
}

-1 आपका जवाब पता चलता है कि &है केवल एक बिटवाइज़ ऑपरेटर, लेकिन यह सच नहीं है। यह है भी एक बूलियन "या" ऑपरेटर।
बोहेमियन

@ बोहेमियन: सिर ऊपर करने के लिए धन्यवाद। true & falseअसत्य का मूल्यांकन करता है। क्या आप इस "बूलियन" या "ऑपरेटर" को समझा सकते हैं? हो सकता है कि मुझे वह नहीं मिल रहा हो जो आप कहना चाह रहे हैं।
भेश गुरुंग

सॉरी - मेरा मतलब बूलियन था AND, नहीं OR! यानी true & falseवैध सिंटैक्स है। -1 हटाया :)
बोहेमियन

4

सादे शब्दों में, शॉर्ट-सर्कुलेटिंग का मतलब है मूल्यांकन रोकना एक बार जब आप जानते हैं कि उत्तर अब बदल नहीं सकता है। उदाहरण के लिए, यदि आप तार्किक ANDएस की एक श्रृंखला का मूल्यांकन कर रहे हैं और आप FALSEउस श्रृंखला के बीच में एक खोज करते हैं , तो आप जानते हैं कि परिणाम गलत होने वाला है, कोई फर्क नहीं पड़ता कि श्रृंखला में बाकी अभिव्यक्तियों के मूल्य क्या हैं। वही ORएस की एक श्रृंखला के लिए जाता है : एक बार जब आप एक खोज करते हैं TRUE, तो आप तुरंत उत्तर जानते हैं, और इसलिए आप बाकी अभिव्यक्तियों का मूल्यांकन करना छोड़ सकते हैं।

आप जावा को इंगित करते हैं कि आप &&इसके बजाय &और के ||बजाय का उपयोग करके शॉर्ट-सर्किटिंग चाहते हैं |। आपकी पोस्ट का पहला सेट शॉर्ट-सर्कुलेटिंग है।

ध्यान दें कि यह कुछ सीपीयू चक्रों को बचाने के प्रयास से अधिक है: इस तरह के भावों में

if (mystring != null && mystring.indexOf('+') > 0) {
    ...
}

शॉर्ट-सर्कुलेटिंग का अर्थ है सही संचालन और क्रैश के बीच का अंतर (मामले में जहां रहस्यपूर्ण शून्य है)।


2

जावा दो दिलचस्प बूलियन ऑपरेटर प्रदान करता है जो अधिकांश अन्य कंप्यूटर भाषाओं में नहीं मिलता है। AND और OR के इन द्वितीयक संस्करणों को शॉर्ट-सर्किट लॉजिकल ऑपरेटर्स के रूप में जाना जाता है । जैसा कि आप पूर्ववर्ती तालिका से देख सकते हैं, OR ऑपरेटर सत्य होने पर A सत्य है, कोई फर्क नहीं पड़ता कि B क्या है।

इसी तरह, A के गलत होने पर AND ऑपरेटर गलत होता है, कोई फर्क नहीं पड़ता कि B क्या है। आप का उपयोग करते हैं ||और &&रूपों के बजाय |और &इन ऑपरेटरों के रूपों, जावा दायां संकार्य अकेले मूल्यांकन करने के लिए परेशान नहीं करेगा। यह तब बहुत उपयोगी होता है जब दाहिने हाथ का संचालन सही ढंग से काम करने के लिए बाईं ओर सही या गलत होने पर निर्भर करता है।

उदाहरण के लिए, निम्न कोड टुकड़ा दिखाता है कि आप शॉर्ट-सर्किट तार्किक मूल्यांकन का लाभ कैसे उठा सकते हैं यह सुनिश्चित करने के लिए कि इसका मूल्यांकन करने से पहले एक डिवीजन ऑपरेशन मान्य होगा:

if ( denom != 0 && num / denom >10)

चूंकि AND ( &&) के शॉर्ट-सर्किट फॉर्म का उपयोग किया जाता है, इसलिए रन-टाइम अपवाद को शून्य से विभाजित करने का कोई जोखिम नहीं है। यदि कोड की इस पंक्ति को &AND के एकल संस्करण का उपयोग करके लिखा गया था , तो दोनों पक्षों का मूल्यांकन करना होगा, जिससे denomशून्य होने पर एक रन-टाइम अपवाद हो सकता है।

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

 if ( c==1 & e++ < 100 ) d = 100;

इधर, एक एकल का उपयोग कर &यह सुनिश्चित है कि वेतन वृद्धि आपरेशन को लागू किया जाएगा eकि क्या cहै 1 या नहीं के बराबर।


2

तार्किक OR: - कम से कम एक ऑपरेंड के सही होने का मूल्यांकन करने पर सही होता है। OR ऑपरेटर को लागू करने से पहले दोनों ऑपरेंड का मूल्यांकन किया जाता है।

शॉर्ट सर्किट OR: - यदि लेफ्ट हैंड साइड ऑपरेंड सही रहता है, तो यह राइट हैंड साइड ऑपरेंड का मूल्यांकन किए बिना सही हो जाता है।


2

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

एक तार्किक आपरेशन के साथ, आप क्योंकि कुछ मामलों में (के पहले संकार्य की तरह लघु सर्किटिंग कर सकते हैं &&किया जा रहा है false, या के पहले संकार्य ||जा रहा है true), तो आपको अभिव्यक्ति के बाकी मूल्यांकन करने की जरूरत नहीं है। nullकिसी दायर या विधि तक पहुँचने से पहले जाँच करने और उनके द्वारा विभाजित होने से पहले संभावित शून्य की जाँच करने जैसी चीजों के लिए यह बहुत उपयोगी है। एक जटिल अभिव्यक्ति के लिए, अभिव्यक्ति के प्रत्येक भाग का पुनरावर्ती रूप से एक ही तरीके से मूल्यांकन किया जाता है। उदाहरण के लिए, निम्नलिखित मामले में:

((== 7) || ( (1 == 3) और& (4 == 4))

केवल बल वाले भागों का मूल्यांकन किया जाएगा। गणना करने के लिए ||, पहले जाँच करें कि क्या 7 == 8है true। यदि ऐसा होता, तो दाहिने हाथ की ओर पूरी तरह से छोड़ दिया जाता। दाहिने हाथ की ओर केवल अगर जाँच करता 1 == 3है false। चूंकि यह है, 4 == 4जाँच करने की आवश्यकता नहीं है, और पूरी अभिव्यक्ति का मूल्यांकन करता है false। यदि बाएं हाथ की ओर true, उदाहरण 7 == 7के लिए 7 == 8, पूरे दाहिने हाथ की तरफ छोड़ दिया जाएगा क्योंकि पूरी ||अभिव्यक्ति की trueपरवाह किए बिना किया जाएगा ।

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


1
if(demon!=0&& num/demon>10)

चूंकि AND (&&) के शॉर्ट-सर्किट फॉर्म का उपयोग किया जाता है, दानव के शून्य होने पर रन-टाइम अपवाद पैदा करने का कोई जोखिम नहीं है।

संदर्भ। हरबर्ट स्किल्ट द्वारा जावा 2 फिफ्थ एडिशन

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