उद्देश्य- C: BOOL बनाम बूल


192

मैंने "नया प्रकार" BOOL( YES, NO) देखा।

मैंने पढ़ा कि यह प्रकार लगभग एक चार की तरह है।

परीक्षण के लिए मैंने किया:

NSLog(@"Size of BOOL %d", sizeof(BOOL));
NSLog(@"Size of bool %d", sizeof(bool));

यह देखने के लिए अच्छा है कि दोनों लॉग "1" प्रदर्शित करते हैं (कभी-कभी C ++ बूल में एक इंट होता है और इसका आकार 4 होता है)

तो मैं सोच रहा था कि क्या बूल टाइप के साथ कुछ मुद्दे थे या कुछ और?

क्या मैं गति खोए बिना बस बूल (जो काम करने लगता है) का उपयोग कर सकता हूं?

जवाबों:


198

परिभाषा में से objc.h:

#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
typedef bool BOOL;
#else
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

#define YES ((BOOL)1)
#define NO  ((BOOL)0)

तो, हाँ, आप मान सकते हैं कि BOOL एक चार है। आप (C99) boolप्रकार का उपयोग कर सकते हैं , लेकिन Apple के सभी ऑब्जेक्टिव-सी फ्रेमवर्क और अधिकांश ऑब्जेक्टिव-सी / कोको कोड BOOL का उपयोग करते हैं, इसलिए यदि आप कभी BOOL का उपयोग करके टाइप करते हैं, तो आप खुद को सिरदर्द से बचा लेंगे।


17
"सभी एप्पल के ढांचे" - सच नहीं है। CGGeometry.h पर एक नज़र डालें, विशेष रूप से: CG_INLINE बूल __CGPointEqualToPoint (CGPoint point1, CGPoint point2) {return point1.x == point2.x && point1 .y == point2.y; }
इलियट

58
@Elliot आप सही हैं। C के कई फ्रेमवर्क (CoreFoundation, CoreGraphics, आदि) C99 का उपयोग करते हैं bool। सभी उद्देश्य-सी रूपरेखा का उपयोग करते हैं BOOL
बैरी वार्क

@ C @ur आपने BOOL कोड नमूने की परिभाषा संपादित की है, लेकिन नीचे दिया गया पाठ समान है। यह थोड़ा भ्रमित करने वाला है और गलत है। मेरा जवाब देखिए।
उत्सुक

विभिन्न व्यवहार जानने के लिए नीचे देखें। NSInteger progressTime = 2;//any value NSInteger totalTime = 1;//any value BOOL success = (progressTime>=totalTime)// यह हमेशा होता है देता है NO लेकिन एक बार मुझे लगता है कि प्राप्त (progressTime>=totalTime)में मूल्य boolप्रकार successयह सही परिणाम देता है। मैं इस व्यवहार को नहीं समझता। मैं उपयोग कर रहा हूं Xcode 7.xऔर iOSसंस्करण था 8.x। @BarryWark
कमर शाद

34

जैसा कि ऊपर उल्लेख किया गया है, BOOL एक हस्ताक्षरित चार है। बूल - C99 मानक (int) से टाइप करें।

BOOL - हाँ / नहीं। बूल - सच्चा / झूठा।

उदाहरण देखें:

bool b1 = 2;
if (b1) printf("REAL b1 \n");
if (b1 != true) printf("NOT REAL b1 \n");

BOOL b2 = 2;
if (b2) printf("REAL b2 \n");
if (b2 != YES) printf("NOT REAL b2 \n");

और परिणाम है

असली b1
असली b2
नहीं असली b2

ध्यान दें कि बूल! = BOOL। नीचे दिए गए परिणाम केवल ONCE AGAIN - REAL b2 है

b2 = b1;
if (b2) printf("ONCE AGAIN - REAL b2 \n");
if (b2 != true) printf("ONCE AGAIN - NOT REAL b2 \n");

यदि आप बूल को BOOL में बदलना चाहते हैं तो आपको अगले कोड का उपयोग करना चाहिए

BOOL b22 = b1 ? YES : NO; //and back - bool b11 = b2 ? true : false;

तो, हमारे मामले में:

BOOL b22 = b1 ? 2 : NO;
if (b22)    printf("ONCE AGAIN MORE - REAL b22 \n");
if (b22 != YES) printf("ONCE AGAIN MORE- NOT REAL b22 \n");

और इसलिए .. अब हमें क्या मिलेगा? :-)


3
आप टर्नरी ऑपरेटर का उपयोग करने के बजाय कर सकते हैं !!b1। उनके बीच बदलने के लिए
रिचर्ड जे। रॉस III

1
मेरे iPhone SE सिम्युलेटर पर 'NOT REAL b2' नहीं छपा है।
गेबलर

12

लेखन के समय यह objc.h का सबसे नवीनतम संस्करण है:

/// Type to represent a boolean value.
#if (TARGET_OS_IPHONE && __LP64__)  ||  TARGET_OS_WATCH
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

इसका मतलब है कि 64-बिट आईओएस डिवाइस और वॉचओएस BOOLपर बिल्कुल वैसा ही है जैसे boolअन्य सभी डिवाइस (ओएस एक्स, 32-बिट आईओएस) पर है signed charऔर यह कंपाइलर फ्लैग द्वारा ओवरराइड भी नहीं किया जा सकता है-funsigned-char

इसका अर्थ यह भी है कि यह उदाहरण कोड अलग-अलग प्लेटफ़ॉर्म पर अलग-अलग तरीके से चलेगा (स्वयं इसका परीक्षण किया है):

int myValue = 256;
BOOL myBool = myValue;
if (myBool) {
    printf("i'm 64-bit iOS");
} else {
    printf("i'm 32-bit iOS");
}

BTW कभी भी वैरिएबल जैसी चीजों को असाइन नहीं array.countकरता BOOLहै क्योंकि लगभग 0.4% संभावित मान नकारात्मक होंगे।


जब आप iOS 32 बिट्स (iPhone 5C ...) के लिए संकलित करते हैं, तो कंपाइलर एक त्रुटि उत्पन्न करेगा यदि आप एक ब्लॉक के एक पैरामीटर के रूप में बूल का उपयोग करते हैं जिसे BOOL (UIView एनीमेशन ब्लॉक, उदाहरण के लिए) के रूप में परिभाषित किया गया है। मैं अपने कोड में हर जगह C ++ बूल का उपयोग करता हूं, और BOOL
स्टीफन k के

8

ऑब्जेक्टिव-सी टाइप आपको इस्तेमाल करना चाहिए BOOL। एक देशी बूलियन डेटाटाइप जैसा कुछ भी नहीं है, इसलिए यह सुनिश्चित करने के लिए कि कोड सभी संकलक उपयोग पर संकलित करता है BOOL। (इसे Apple-चौखटे में परिभाषित किया गया है।


2
यह कड़ाई से सटीक नहीं है। BOOLउद्देश्य-सी भाषा द्वारा परिभाषित किया गया है (यह objc/*.hहेडर में से एक में है ), फ्रेमवर्क द्वारा नहीं। इसके अलावा, जब C99 (जो मुझे लगता है कि डिफ़ॉल्ट है) के साथ संकलन है, तो एक देशी बूलियन प्रकार है, _Bool(या boolयदि stdbool.hशामिल है)।
ड्रीमलैक्स

5

हाँ, BOOL एकjj के अनुसार हस्ताक्षर किए गए चार्ट के लिए एक टाइपराइफ़ है।

हालांकि, मैं बूल के बारे में नहीं जानता। यह एक सी ++ बात है, है ना? यदि इसे एक हस्ताक्षरित चार के रूप में परिभाषित किया जाता है जहां 1 YES / true है और 0 NO / गलत है, तो मुझे लगता है कि यह कोई फर्क नहीं पड़ता कि आप किसका उपयोग करते हैं।

चूंकि BOOL ऑब्जेक्टिव-सी का हिस्सा है, हालांकि, यह संभवतः स्पष्टता के लिए BOOL का उपयोग करने के लिए अधिक समझ में आता है (यदि वे उपयोग में एक बूल देखते हैं तो अन्य ऑब्जेक्टिव-सी डेवलपर्स हैरान हो सकते हैं)।


6
_Bool C99 में परिभाषित किया गया है, और मानक हेडर stdbool.h में, मैक्रो बूल परिभाषित किया गया है (जो _Bool तक फैलता है) और सच / गलत यहाँ भी परिभाषित किया गया है।
ब्रायन मिशेल

4

बूल और BOOL के बीच एक और अंतर यह है कि वे ठीक उसी तरह की वस्तुओं में परिवर्तित नहीं होते हैं, जब आप कुंजी-मूल्य का अवलोकन करते हैं, या जब आप तरीकों का उपयोग करते हैं - [NSObject valueForKey:]।

जैसा कि सभी ने कहा है, BOOL चार है। जैसे, यह एक NSNumber में एक चार पकड़ में परिवर्तित हो जाता है। यह ऑब्जेक्ट 'A' या '\ 0' जैसे एक नियमित चार से बनाए गए NSNumber से अप्रभेद्य है। आपने पूरी तरह से एक BOOL की जानकारी खो दी है।

हालांकि, बूल को CFBoolean में बदल दिया जाता है, जो NSNumber के समान होता है, लेकिन जो वस्तु के बूलियन मूल को बनाए रखता है।

मुझे नहीं लगता कि यह BOOL बनाम बूल बहस में एक तर्क है, लेकिन यह आपको एक दिन काट सकता है।

सामान्यतया, आपको BOOL के साथ जाना चाहिए, क्योंकि यह कोको / iOS APIs (C99 और इसके मूल बूल प्रकार से पहले डिज़ाइन किया गया) में हर जगह उपयोग किया जाता है।


2

स्वीकृत उत्तर को संपादित कर दिया गया है और इसका स्पष्टीकरण थोड़ा गलत हो गया है। कोड नमूना ताज़ा किया गया है, लेकिन नीचे का पाठ समान है। आप यह नहीं मान सकते हैं कि BOOL अब के लिए एक चार है क्योंकि यह वास्तुकला और मंच पर निर्भर करता है। इस प्रकार, यदि आप 32 बिट प्लेटफ़ॉर्म (उदाहरण के लिए iPhone 5) पर कोड चलाते हैं और @encode (BOOL) प्रिंट करते हैं, तो आप "c" देखेंगे। यह एक चार प्रकार से मेल खाती है । लेकिन अगर आप आईफोन 5 एस (64 बिट) पर आपको कोड चलाते हैं तो आपको "बी" दिखाई देगा। यह एक बूल प्रकार से मेल खाती है ।


1

मैं यहां अधिवेशन के खिलाफ जाता हूं। मुझे टाइप के आधार टाइप करने के लिए पसंद नहीं है। मुझे लगता है कि यह एक बेकार अप्रत्यक्ष है जो मूल्य को हटा देता है।

  1. जब मैं आपके स्रोत में आधार प्रकार देखता हूं तो मैं तुरंत इसे समझूंगा। अगर यह एक टाइप्डिफ है तो मुझे यह देखना होगा कि मैं वास्तव में क्या कर रहा हूं।
  2. जब दूसरे कंपाइलर के लिए पोर्टिंग करते हैं या किसी अन्य लाइब्रेरी को जोड़ते हैं, तो उनके टाइपपैड्स का सेट संघर्ष कर सकता है और उन मुद्दों का कारण बन सकता है जो डिबग करना मुश्किल हैं। मैं वास्तव में इस के साथ काम कर रहा हूँ। एक पुस्तकालय में बूलियन को int में टाइप किया गया था, और mingw / gcc में यह chared के लिए टाइप किया गया है।

4
खैर ... आप कर सकते हैं मानक typedef अपनी भाषा (लगता है की है पता करने के लिए उम्मीद की जा size_t), और दोनों bool(C99) और BOOL(ObjC) उस श्रेणी में आते हैं। और यदि आपका कोड टाइपडेफ़ के परिवर्तन के कारण विफल हो गया, तो यह आपका कोड है क्योंकि आप स्पष्ट रूप से टाइपफ़ेड को एक अपारदर्शी चीज़ के रूप में नहीं संभालते थे, लेकिन एक मंच पर इसके कार्यान्वयन पर निर्भर थे। (शर्मिंदा होने के लिए कुछ भी नहीं है, ऐसा होता है, लेकिन यह दोष देने के लिए टाइपराइफ नहीं है।)
DevSolar

1
"मानक" टाइपडिफ्स बहुत मानक नहीं लगते हैं (उदाहरण के लिए थोड़ी देर के लिए एमएस पॉज़िक्स मानकों, आदि का समर्थन नहीं करता था)। यदि आप टाइपडिफ का उपयोग नहीं करते हैं तो विभिन्न कंपाइलरों पर टाइप करने या अलग-अलग होने के साथ समस्या को समाप्त कर दिया जाता है।
जय

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

2
@ जय: क्षमा करें, मुझे समझाना चाहिए था कि यह "गलत प्रवृत्ति" क्यों अच्छी है। मैं एक उदाहरण प्रदान करने का प्रयास करूँगा: यदि आप एक int या char का उपयोग करने के बजाय सीधे typedef'd बूलियन का उपयोग करते हैं तो आप एक अलग प्रकार (जो अभी भी काम करते हैं) को आपके कोड को तोड़ने के बिना प्रत्येक प्लेटफ़ॉर्म पर उपयोग करने की अनुमति देते हैं [कारणों के लिए] यह भिन्न होता है, लेकिन हम एक ऐसे मंच की कल्पना कर सकते हैं, जहां एक मेमोरी में एक चार्ट का गलत इस्तेमाल किया जा सकता है और इस तरह धीमी गति से इंट का उपयोग बूलियन के लिए किया जा सकता है]।
जोआ पोएला

2
@Jay: द्वारा "अच्छा अर्थ विज्ञान" मेरा मतलब है कि आप अपने बूलियन घोषित जब BOOL varnameबजाय char varnameइसे और अधिक स्पष्ट है कि उस चर के लिए दो वैध मान हैं true/ YESया false/ NO
जोआओ पोर्टेला

1

जैसा कि ऊपर बताया गया है कि आपकी वास्तुकला के आधार पर BOOLएक unsigned charप्रकार हो सकता है , जबकि boolप्रकार का है int। एक साधारण प्रयोग से अंतर दिखाई देगा कि BOOL और बूल अलग-अलग व्यवहार क्यों कर सकते हैं:

bool ansicBool = 64;
if(ansicBool != true) printf("This will not print\n");

printf("Any given vlaue other than 0 to ansicBool is evaluated to %i\n", ansicBool);

BOOL objcBOOL = 64;
if(objcBOOL != YES) printf("This might print depnding on your architecture\n");

printf("BOOL will keep whatever value you assign it: %i\n", objcBOOL);

if(!objcBOOL) printf("This will not print\n");

printf("! operator will zero objcBOOL %i\n", !objcBOOL);

if(!!objcBOOL) printf("!! will evaluate objcBOOL value to %i\n", !!objcBOOL);

आपके आश्चर्य if(objcBOOL != YES)करने के लिए संकलक द्वारा 1 का मूल्यांकन किया जाएगा, क्योंकि YESवास्तव में चरित्र कोड 1 है, और संकलक की दृष्टि में, चरित्र कोड 64 निश्चित रूप से वर्ण कोड 1 के बराबर नहीं है, इस प्रकार यदि कथन का मूल्यांकन होगा YES/true/1और निम्न पंक्ति का होगा Daud। हालाँकि, कोई भी शून्य boolप्रकार हमेशा 1 के पूर्णांक मान का मूल्यांकन नहीं करता है, उपरोक्त समस्या आपके कोड को प्रभावित नहीं करेगी। नीचे कुछ अच्छे सुझाव दिए गए हैं यदि आप Objective-C BOOLटाइप बनाम टाइप का उपयोग करना चाहते हैं ANSI C bool:

  • हमेशा YESया NOमान को असाइन करें और कुछ नहीं।
  • अप्रत्याशित परिणामों से बचने के लिए BOOLडबल !!नॉट ऑपरेटर का उपयोग करके प्रकार परिवर्तित करें ।
  • YESउपयोग के लिए जाँच करते समय if(!myBool) instead of if(myBool != YES)यह बहुत साफ होता है कि !ऑपरेटर नहीं और अपेक्षित परिणाम देता है।

1

इसके अलावा, कास्टिंग में अंतर के बारे में पता होना चाहिए, खासकर जब हस्ताक्षर किए चार के लिए कास्टिंग के कारण बिटमास्क के साथ काम करते हैं:

bool a = 0x0100;
a == true;  // expression true

BOOL b = 0x0100;
b == false; // expression true on !((TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH), e.g. MacOS
b == true;  // expression true on (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH

अगर BOOL एक बूल के बजाय एक हस्ताक्षरित चार है, तो BOx को 0x0100 का कास्ट केवल सेट बिट ड्रॉप करता है, और परिणामी मान 0 होता है।

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