बूल ऑपरेटर ++ और -


104

आज कुछ विज़ुअल C ++ कोड लिखते समय मैं कुछ ऐसी चीजों के बारे में आया हूं जिसने मुझे आश्चर्यचकित कर दिया है। ऐसा लगता है कि C ++ बूल के लिए ++ (वेतन वृद्धि) का समर्थन करता है, लेकिन नहीं (- वेतन वृद्धि)। यह सिर्फ एक यादृच्छिक निर्णय है, या इसके पीछे कोई कारण है?

यह संकलन:

static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
    hMod = LoadLibrary("xxx");

यह नहीं करता:

static HMODULE hMod = NULL;
static bool once = true;
if (once--)
    hMod = LoadLibrary("xxx");

2
hm, xcode और gcc संकलक के लिए समान
व्लादिमीर

हाँ, ++onceऔर once++जीसीसी के साथ काम करते हैं, लेकिन वेतन वृद्धि नहीं।
जस्टिन अरदिनी

हो सकता है कि "ऑपरेटर-कीवर्ड" के बजाय "इतिहास" को फिर से तैयार किया जाए, इसलिए इसे अन्य सभी मज़ेदार स्पष्टीकरणों के साथ समूहीकृत किया गया है क्योंकि यदि आप इतिहास पर विचार करते हैं तो विभिन्न पागल चीजें उचित क्यों हैं? :)
जॉन हैना

C ++ 17 के रूप में नोट के लिए पूर्व वेतन वृद्धि ऑपरेटर boolपदावनत है, souce
cog

इसे std::exchange(once,false)(नोट: परमाणु नहीं ) से बदला जा सकता है , यदि आप कुछ गैर-वंचित चाहते हैं।
गोल्वोक

जवाबों:


90

यह पूर्णांक मानों को बूलियन के रूप में उपयोग करने के इतिहास से आता है।

यदि xकोई है int, लेकिन मैं इसे एक बूलियन के रूप में उपयोग कर रहा हूं if(x)...तो वेतन वृद्धि का मतलब यह होगा कि ऑपरेशन से पहले इसका सत्य मूल्य जो भी हो, इसके trueबाद इसका सत्य-मूल्य होगा (अतिप्रवाह को छोड़कर)।

हालाँकि, --केवल दिए गए ज्ञान के सत्य मूल्य के परिणाम की भविष्यवाणी करना असंभव है x, क्योंकि इसमें परिणाम हो सकता है false(यदि अभिन्न मूल्य 1 है) या true(यदि अभिन्न मूल्य कुछ और है - विशेष रूप से इसमें 0 [ false] और 2 शामिल हैं) अधिक [ true])।

तो एक शॉर्ट-हैंड के रूप में ++काम किया, और --नहीं किया।

++ इसके साथ संगतता के लिए बूल पर अनुमति दी जाती है, लेकिन इसका उपयोग मानक में पदावनत है।


यह मानता है कि मैं केवलx एक बूलियन के रूप में उपयोग करता हूं , जिसका अर्थ है कि अतिप्रवाह तब तक नहीं हो सकता है जब तक कि मैंने ++अक्सर ऐसा नहीं किया है क्योंकि यह स्वयं पर अतिप्रवाह का कारण बनता है। यहां तक ​​कि चार के रूप में इस्तेमाल किया गया है और CHAR_BITS5 की तरह कुछ कम है, जो कि 32 बार है इससे पहले कि यह किसी भी अधिक काम नहीं करता है (यह अभी भी एक बुरा अभ्यास होने के लिए पर्याप्त तर्क है, मैं अभ्यास का बचाव नहीं कर रहा हूं, बस यह समझाता हूं कि यह क्यों काम करता है) 32-बिट के लिए intहम निश्चित रूप से ++2 ^ 32 बार उपयोग करना होगा इससे पहले कि यह एक मुद्दा है। साथ --ही यह केवल में परिणाम होगा falseअगर मैं के लिए 1 का मान के साथ शुरू किया true, या 0 के साथ शुरू किया और इस्तेमाल ++ठीक पहले एक बार।

यह भिन्न है अगर हम एक मान से शुरू करते हैं जो सिर्फ कुछ नीचे है। वास्तव में, ऐसे मामले में हम अंततः मूल्य ++में परिणाम करना चाहते हैं falseजैसे:

int x = -5;
while(++x)
  doSomething(x);

हालांकि, यह उदाहरण सशर्त को छोड़कर हर जगह के xरूप में व्यवहार करता है int, इसलिए यह इसके बराबर है:

int x = -5;
while(++x != 0)
  doSomething(x);

जो केवल xबूलियन के रूप में उपयोग करने के लिए अलग है ।


1
धन्यवाद। यह जानने के लिए कि मैं अभी भी इस तरह के लोगों को जवाब दे सकता हूं, यह देखते हुए कि यह वास्तव में C ++ की एक पंक्ति है, तब तक दिया है
जॉन हैना

8
लेकिन अगर x -1 था (VB जैसे कुछ प्लेटफार्मों में TRUE), ++ x FALSE होगा।
जेम्स कर्रान

4
@ जेम्स, सी और सी ++ में वह मामला होगा जो मैं तब सोच रहा था जब मैंने कहा ("बैरिंग ओवरफ्लो")। वास्तव में VB में किसी भी गैर-शून्य का सत्य मूल्य TRUE है (C की तरह), लेकिन उनके पास 1 है, बल्कि 1 के बजाय सच्चे बूलियन ऑपरेशन के परिणाम के रूप में तब NOT (TRUE) FALSE है, NOT (FALSE) TRUE है, x OR TRUE TRUE है, x या FALSE x है, x और FALSE FALSE है और x और TRUE x है, आदि बूलियन और बिट-वार ऑपरेशंस के लिए एक ही ऑपरेटर का उपयोग करते हैं (क्योंकि VB द्वारा माना जाता है कि डोज़-सप्लीमेंट -1 -1 सभी 1 बिट्स हैं)। हालाँकि, यह VB में कुछ अजीब बग पैदा कर सकता है अगर कोडर उस 2 (सत्य) और 4 को नहीं पकड़ता है (0) (0) (सत्य) में परिणाम।
जॉन हन्ना

2
@ जोहन्ना: एएनएसआई C89 पहला C मानक था। ANSI C समिति ने <limits.h>हेडर और CHAR_BITमैक्रो का आविष्कार किया । उससे पहले, मुझे लगता है कि सैद्धांतिक रूप से कार्यान्वयन हो सकता है जहां char8 बिट्स की तुलना में संकीर्ण है, लेकिन जहां तक ​​मुझे पता है कि कोई भी नहीं था। विशेष रूप से, K & R1 (1978 में प्रकाशित) में 4 नमूना कार्यान्वयन सूचीबद्ध हैं, जिनमें से सभी में 8-बिट या 9-बिट हैं char
कीथ थॉम्पसन

1
@JonHanna: एक अनुरूप सी कार्यान्वयन करना होगा है CHAR_BIT >= 8। मानक उन लक्ष्यों के लिए भत्ते नहीं देता है जहां यह मुश्किल है। (आप एक गैर-अनुरूप कार्यान्वयन हो सकते हैं, निश्चित रूप से।)
कीथ थॉम्पसन

29

ANSI ISO IEC 14882 2003 (c ++ 03):

5.2.6-2

पोस्टफिक्स का ऑपरेंड - पोस्टफिक्स ++ ऑपरेटर के अनुरूप समान रूप से घटाया जाता है, सिवाय इसके कि ऑपरेंड टाइप बूल का नहीं होगा। [नोट: उपसर्ग वृद्धि और गिरावट के लिए, ५.३.२ देखें। ]

और बेवजह ...

5.3.2-2

उपसर्ग के ऑपरेंड - को घटाकर संशोधित किया जाता है। ऑपरेंड टाइप बूल का नहीं होगा। उपसर्ग के ऑपरेंड पर आवश्यकताएं - और इसके परिणाम के गुण अन्यथा उपसर्ग ++ के समान हैं। [नोट: पोस्टफिक्स इन्क्रीमेंट और डीक्रीमेंट के लिए, ५.२.६ देखें। ]

इसके अलावा 5.6.2-1 और 5.3.2-1 में उल्लेख है कि बूलों के लिए ++ सही होगा और अनुलग्नक डी -1 का कहना है कि ++ को डिप्रेस्ड में बूल पर।


3
@ बालूराज: जॉन हैना का जवाब देखें।
जस्टिन अर्दिनी

9

ऐतिहासिक कारणों के कारण इसका समर्थन किया गया था। लेकिन ध्यान दें कि ... ++ ऑपरेटर के साथ प्रकार बूल के एक ऑपरेंड का उपयोग पदावनत है सी ++ मानक (n3092) में धारा 5.3.2 देखें

५.३.२ वृद्धि और गिरावट [expr.pre.incr]

  • उपसर्ग ++ का संचालक 1 जोड़कर संशोधित किया गया है या यह सच है कि यह बूल है (यह उपयोग पदावनत है)। ऑपरेंड एक परिवर्तनीय अंतराल होगा। ऑपरेंड का प्रकार एक अंकगणितीय प्रकार या पूरी तरह से परिभाषित ऑब्जेक्ट प्रकार का सूचक होगा। परिणाम अद्यतन ऑपरेंड है; यदि यह एक बिट फ़ील्ड है, तो यह एक अंतराल है, और यह एक बिट-फ़ील्ड है। यदि x प्रकार बूल का नहीं है, तो अभिव्यक्ति ++ x, x + = 1 के बराबर है [नोट: रूपांतरण पर जानकारी के लिए जोड़ (5.7) और असाइनमेंट ऑपरेटरों (5.17) की चर्चा देखें। ध्यान दें]
  • उपसर्ग के ऑपरेंड - को घटाकर संशोधित किया जाता है। ऑपरेंड टाइप बूल का नहीं होगा। उपसर्ग के ऑपरेंड पर आवश्यकताएं - और इसके परिणाम के गुण अन्यथा उपसर्ग ++ के समान हैं।

3
  • पुराने मानकों (C ++ 98) के साथ यह एक त्रुटि नहीं है।
  • नए मानकों के साथ एक बूलियन बढ़ाना पदावनत है। (सी ++ 11)
  • आप C ++ 17 तक बूलियन पर वेतन वृद्धि का उपयोग कर सकते हैं।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.