C में कोई अंतर्निहित बूलियन प्रकार नहीं है। सी में उनका उपयोग करने का सबसे अच्छा तरीका क्या है?
C में कोई अंतर्निहित बूलियन प्रकार नहीं है। सी में उनका उपयोग करने का सबसे अच्छा तरीका क्या है?
जवाबों:
सबसे अच्छे से बदतर:
विकल्प 1 (C99)
#include <stdbool.h>
विकल्प 2
typedef enum { false, true } bool;
विकल्प 3
typedef int bool;
enum { false, true };
विकल्प 4
typedef int bool;
#define true 1
#define false 0
यदि आप अनिर्णीत हैं, तो # 1 के साथ जाएं!
<stdbool.h>
bool
संकलक , अनुकूलन और संकलक चुनने का तरीका एक बूलियन मूल्य के इच्छित उद्देश्य के लिए अधिक उपयुक्त हो सकता है, जिसका उपयोग करने की तुलना में बूलियन मूल्य int
(यानी संकलक एक से bool
अलग लागू करने के लिए चुन सकता है int
)। यदि आप भाग्यशाली हैं, तो यह संकलित समय पर कठोर प्रकार की जाँच का परिणाम भी हो सकता है।
int
के लिए bool
? वह बेकार है। का उपयोग करें unsigned char
। या सी के बिलिन का उपयोग करें _Bool
।
सी में बुलियन पर कुछ विचार:
मैं इतना बूढ़ा हो int
चुका हूं कि मैं अपने बूलियन टाइप के बिना किसी भी टाइपिडेफ या विशेष डिफाइन या एनम को सही या झूठे मूल्यों के लिए इस्तेमाल कर रहा हूं । यदि आप बूलियन स्थिरांक के खिलाफ तुलना नहीं करने के बारे में मेरे सुझाव का पालन करते हैं, तो आपको केवल झंडे को आरम्भ करने के लिए 0/1 का उपयोग करना होगा। हालाँकि, इस तरह के दृष्टिकोण को इन आधुनिक समयों में बहुत प्रतिक्रियावादी माना जा सकता है। उस मामले में, किसी को निश्चित रूप <stdbool.h>
से इसका उपयोग करना चाहिए क्योंकि इसका कम से कम मानकीकृत होने का लाभ है।
बूलियन स्थिरांक को जो भी कहा जाता है, उन्हें केवल आरंभीकरण के लिए उपयोग करें। कभी ऐसा कुछ लिखो
if (ready == TRUE) ...
while (empty == FALSE) ...
इन्हें हमेशा क्लीयर द्वारा बदला जा सकता है
if (ready) ...
while (!empty) ...
ध्यान दें कि ये वास्तव में यथोचित और काफी जोर से पढ़ा जा सकता है।
अपने बूलियन चर को सकारात्मक नाम दें, अर्थात full
इसके बजाय notfull
। उत्तरार्द्ध कोड की ओर जाता है जो आसानी से पढ़ना मुश्किल है। तुलना
if (full) ...
if (!full) ...
साथ में
if (!notfull) ...
if (notfull) ...
पूर्व जोड़ी के दोनों स्वाभाविक रूप से पढ़ते हैं, जबकि !notfull
यह पढ़ने के लिए अजीब है, और अधिक जटिल बूलियन अभिव्यक्तियों में बहुत खराब हो जाता है।
आम तौर पर बूलियन तर्कों से बचा जाना चाहिए। इस तरह परिभाषित एक फ़ंक्शन पर विचार करें
void foo(bool option) { ... }
फ़ंक्शन के शरीर के भीतर, यह बहुत स्पष्ट है कि तर्क का क्या मतलब है क्योंकि इसमें एक सुविधाजनक और उम्मीद है कि सार्थक, नाम। लेकिन, कॉल साइट्स जैसी दिखती हैं
foo(TRUE);
foo(FALSE):
यहां, यह बताना असंभव है कि फंक्शन की परिभाषा या घोषणा को देखे बिना पैरामीटर का क्या मतलब है, और यदि आप और भी अधिक बूलियन पैरामीटर जोड़ते हैं तो यह बहुत जल्दी खराब हो जाता है। मैं या तो सुझाव देता हूं
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
या
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
किसी भी स्थिति में, कॉल साइट अब दिखती है
foo(OPT_ON);
foo(OPT_OFF);
पाठक की परिभाषा को कम से कम समझने के बिना कम से कम समझने का मौका है foo
।
a == b
करता है?
a
और b
शून्य से ऊपर गिनती तक, मैं a > 0 == b > 0
बजाय। यदि आप मनमाने ढंग से गैर-शून्य मानों की सत्यता का लाभ उठाने पर जोर देते हैं, !!var
तो बूलियन 0/1 मूल्य के बराबर होता है var
, इसलिए आप लिख सकते हैं !!a == !!b
, हालांकि काफी पाठक इसे भ्रमित पाएंगे।
!a == !b
समानता के परीक्षण के लिए भी पर्याप्त है, गैर शून्य शून्य हो जाते हैं, और शून्य एक हो जाते हैं।
!!a
"गैर-बूलियन को अपने समतुल्य सत्य मूल्य में परिवर्तित करता हूं " के रूप में पढ़ूंगा , जबकि मैं !a
"तार्किक रूप से बूलियन चर को उल्टा" के रूप में पढ़ूंगा। विशेष रूप से, मैं कुछ विशेष कारण की तलाश करूंगा जो तार्किक उलटा वांछित था।
सी में एक बूलियन एक पूर्णांक है: झूठे के लिए शून्य और सत्य के लिए गैर-शून्य।
यह भी देखें बूलियन डेटा प्रकार , खंड सी, सी ++, ऑब्जेक्टिव-सी, AWK ।
यहाँ संस्करण है कि मैं इस्तेमाल किया है:
typedef enum { false = 0, true = !false } bool;
क्योंकि झूठे का केवल एक मूल्य होता है, लेकिन एक तार्किक सत्य के कई मूल्य हो सकते हैं, लेकिन तकनीक यह निर्धारित करने के लिए सही है कि संकलक झूठ के विपरीत के लिए क्या उपयोग करेगा।
यह किसी की कोडिंग की समस्या का ध्यान रखता है जो इस पर उतरता है:
if (true == !false)
मुझे लगता है कि हम सभी सहमत होंगे कि यह एक अच्छा अभ्यास नहीं है, लेकिन एक समय के लिए "सही = गलत" करने की लागत से हम उस समस्या को खत्म कर देते हैं।
[संपादित] अंत में मैं इस्तेमाल किया:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
अन्य योजनाओं के साथ नाम टकराने से बचने के लिए जो परिभाषित कर रहे थे true
औरfalse
। लेकिन अवधारणा वही है।
[संपादित करें] पूर्णांक के बूलियन में रूपांतरण दिखाने के लिए:
mybool somebool;
int someint = 5;
somebool = !!someint;
पहला (सबसे सही)! गैर-शून्य पूर्णांक को 0 में परिवर्तित करता है, फिर दूसरा (सबसे बाएं)! 0 को एक myfalse
मान में परिवर्तित करता है । मैं इसे शून्य पूर्णांक में परिवर्तित करने के लिए पाठक के लिए एक अभ्यास के रूप में छोड़ दूंगा।
[संपादित करें] यह मेरी शैली है कि किसी एनम में मूल्य की स्पष्ट सेटिंग का उपयोग करें जब विशिष्ट मूल्य की आवश्यकता होती है, भले ही डिफ़ॉल्ट मान समान हो। उदाहरण: क्योंकि शून्य की आवश्यकता है कि मैं false = 0,
इसके बजाय शून्य का उपयोग करता हूंfalse,
true
, false
और bool
में हाइलाइट किया जाता सबसे आईडीई के, क्योंकि वे enum मूल्यों और एक typedef, के रूप में करने का विरोध किया हैं #defines
, जो बहुत कम ही ऐसा वाक्य रचना हाइलाइट किए गए हैं।
gcc -ansi -pedantic -Wall
कोई चेतावनी नहीं देता है, इसलिए मुझे भरोसा है gcc
; यदि यह इसके लिए भी काम करता है, तो c89
उसे भी काम करना चाहिए c99
।
!
केवल मान लौटा सकता है 0
और 1
इसलिए true = !false
हमेशा मान प्रदान करेगा 1. यह विधि कोई अतिरिक्त सुरक्षा नहीं देती है typedef enum { false, true } bool;
।
if(!value)
) के लिए मायने नहीं रखता है , लेकिन यह अपवाद इस विशिष्ट मामले में लागू नहीं है।
यदि आप C99 कंपाइलर का उपयोग कर रहे हैं तो इसमें बूल प्रकारों के लिए अंतर्निहित समर्थन है:
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
पहली चीजें पहले। C, यानी ISO / IEC 9899 में 19 वर्षों से बुलियन प्रकार है । इस सवाल पर जाकर संयुक्त रूप से शौकिया / शैक्षणिक / व्यावसायिक भागों के साथ सी प्रोग्रामिंग करियर की अपेक्षित लंबाई से अधिक लंबा समय है । मेरा है कि शायद 1-2 साल से अधिक है। इसका अर्थ है कि उस समय के दौरान जब एक औसत पाठक ने C के बारे में कुछ भी सीखा है, C का वास्तव में बूलियन डेटा प्रकार है ।
डेटाटाइप के लिए #include <stdbool.h>
, और उपयोग करें true
, false
और bool
। या इसे शामिल न करें _Bool
, 1
और उपयोग करें , और 0
इसके बजाय।
इस धागे के अन्य उत्तरों में कई खतरनाक प्रथाओं को बढ़ावा दिया गया है। मैं उन्हें संबोधित करूंगा:
typedef int bool;
#define true 1
#define false 0
यह कोई नहीं-नहीं है, क्योंकि एक आकस्मिक पाठक - जिन्होंने उन 19 वर्षों के भीतर सी सीखा था - उम्मीद करेंगे कि वास्तविक डेटा प्रकार bool
को संदर्भित करता है और इसी तरह का व्यवहार करेगा, लेकिन यह नहीं करता है! उदाहरण के लिए bool
double a = ...;
bool b = a;
C99 bool
/ के साथ _Bool
, iff परb
सेट किया गया था शून्य, और अन्यथा। C11 6.3.1.2p1false
a
true
- जब कोई स्केलर मान परिवर्तित किया जाता है
_Bool
, तो परिणाम 0 होता है यदि मान 0 के बराबर होता है; अन्यथा, परिणाम 1. 59)फुटनोट
59) NaNs 0 के बराबर तुलना नहीं करते हैं और इस प्रकार 1 में बदल जाते हैं।
साथ typedef
जगह में, double
एक करने के लिए मजबूर किया जाएगा int
- अगर डबल का मूल्य रेंज में के लिए नहीं है int
, व्यवहार अपरिभाषित है ।
स्वाभाविक रूप से एक ही है, तो पर लागू होता है true
और false
एक में घोषित किया गया enum
।
क्या और भी खतरनाक है घोषित करना
typedef enum bool {
false, true
} bool;
क्योंकि अब 1 और 0 के अलावा सभी मान अमान्य हैं, और क्या इस तरह का मान उस प्रकार के एक चर को सौंपा जाना चाहिए , व्यवहार पूरी तरह से अपरिभाषित होगा ।
इसलिए अगर आप C99 का इस्तेमाल किसी अक्षम्य कारण के लिए नहीं कर सकते हैं, तो आपके द्वारा उपयोग किए जाने वाले बूलियन चर के लिए:
int
और मान 0
और 1
जैसा है ; और ध्यान से डबल नकारात्मक के साथ किसी भी अन्य मूल्यों से डोमेन रूपांतरण करते हैं!!
BOOL
, TRUE
और FALSE
!int
या unsigned int
एक गणन धारण करने के लिए है, लेकिन मैं मानक में कुछ भी नहीं है कि एक गणना एक पूर्णांक के अलावा और कुछ के रूप में व्यवहार करने के लिए कारण होगा के बारे में पता प्रकार।
typedef enum {
false = 0,
true
} t_bool;
!0 = 1
C मानक द्वारा, और !a = 0
किसी भी गैर-शून्य मान के लिए a
। समस्या यह है कि किसी भी गैर-शून्य को सच माना जाता है। यदि ऐसा है a
और b
दोनों "सच" हैं, तो जरूरी नहीं कि यह मामला 'ए == बी' ही हो।
सी में एक बूलियन प्रकार है: बूल (कम से कम पिछले 10 (!) वर्षों के लिए)
Stdbool.h को शामिल करें और सही / गलत उम्मीद के मुताबिक काम करेगा।
bool
एक मैक्रो होने की आवश्यकता होती है जो फैलता है _Bool
। यह अंतर इसलिए मायने रखता है क्योंकि आप #undef
एक मैक्रो (और इसकी अनुमति हो सकती है, कम से कम एक संक्रमणकालीन उपाय के रूप में), लेकिन आप untypedef
टाइप नहीं कर सकते । हालांकि यह आपकी पहली टिप्पणी के मुख्य जोर को बदल नहीं सकता है।
कुछ भी नॉनजरो का मूल्यांकन बूलियन ऑपरेशन में सच है, तो आप बस कर सकते हैं
#define TRUE 1
#define FALSE 0
और स्थिरांक का उपयोग करें।
यदि आप C99 का उपयोग करने की अनुमति देते हैं, तो अन्य उत्तरों और कुछ स्पष्टीकरण के पूरक हैं।
+-------+----------------+-------------------------+--------------------+
| Name | Characteristic | Dependence in stdbool.h | Value |
+-------+----------------+-------------------------+--------------------+
| _Bool | Native type | Don't need header | |
+-------+----------------+-------------------------+--------------------+
| bool | Macro | Yes | Translate to _Bool |
+-------+----------------+-------------------------+--------------------+
| true | Macro | Yes | Translate to 1 |
+-------+----------------+-------------------------+--------------------+
| false | Macro | Yes | Translate to 0 |
+-------+----------------+-------------------------+--------------------+
मेरी कुछ प्राथमिकताएँ:
_Bool
या bool
? दोनों ठीक हैं, लेकिनbool
कीवर्ड से बेहतर है_Bool
।bool
और _Bool
हैं: false
या true
। नियत 0
या 1
के बजाय false
याtrue
मान्य है, लेकिन पढ़ने के लिए और तर्क प्रवाह को समझने के लिए कठिन है।मानक से कुछ जानकारी:
_Bool
नहीं है unsigned int
, लेकिन अहस्ताक्षरित पूर्णांक प्रकार के समूह का हिस्सा है । यह मूल्यों को धारण करने के लिए काफी बड़ा है0
या1
।bool
true
औरfalse
निश्चित रूप से एक अच्छा विचार नहीं है। इस क्षमता को अश्लील माना जाता है और भविष्य में इसे हटा दिया जाएगा।_Bool
या bool
, यदि स्केलर का मूल्य बराबर है 0
या इसकी तुलना 0
होगी 0
, अन्यथा परिणाम है 1
:_Bool x = 9;
9
को 1
असाइन किए जाने पर परिवर्तित किया जाता है x
।_Bool
1 बाइट (8 बिट) है, आमतौर पर प्रोग्रामर को अन्य बिट्स का उपयोग करने की कोशिश करने के लिए लुभाया जाता है, लेकिन इसकी सिफारिश नहीं की जाती है, क्योंकि केवल जो गारंटी दी जाती है वह यह है कि डेटा को स्टोर करने के लिए केवल एक बिट का उपयोग किया जाता है, न char
कि उस प्रकार का जैसे 8 उपलब्ध बिट्स।आप इसके लिए एक चार, या एक और छोटी संख्या के कंटेनर का उपयोग कर सकते हैं।
छद्म कोड
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
int
) का उपयोग करना हमेशा बेहतर होता है , क्योंकि कुछ आर्किटेक्चर पर आपको इन वेरिएबल्स पर अनपैक / मास्क चेक करने से महत्वपूर्ण प्रदर्शन हिट मिलता है।
आप _Bool का उपयोग कर सकते हैं, लेकिन रिटर्न मान एक पूर्णांक होना चाहिए (1 सत्य के लिए, 0 झूठे के लिए)। हालाँकि, यह C ++ की तरह बूल को शामिल करने और उपयोग करने के लिए अनुशंसित है, जैसा कि इस उत्तर में daniweb मंच से कहा गया है , साथ ही साथ यह उत्तर , इस अन्य स्टैकओवरफ़्लो प्रश्न से:
_बूल: C99 का बूलियन प्रकार। _Bool का उपयोग सीधे केवल तभी किया जाता है यदि आप विरासत कोड बनाए रख रहे हैं जो पहले से ही मैक्रोज़ को बूल, ट्रू या गलत के लिए परिभाषित करता है। अन्यथा, उन मैक्रो को हेडर में मानकीकृत किया जाता है। उस शीर्ष लेख को शामिल करें और आप C ++ में उसी तरह बूल का उपयोग कर सकते हैं।
सशर्त अभिव्यक्तियों को सत्य माना जाता है यदि वे गैर-शून्य हैं, लेकिन सी मानक के लिए आवश्यक है कि तार्किक ऑपरेटर स्वयं या तो 0 या 1 पर लौटें।
@Tom: #define TRUE! FALSE खराब है और पूरी तरह से बेकार है। यदि हेडर फ़ाइल संकलित C ++ कोड में अपना रास्ता बनाती है, तो यह समस्याओं का कारण बन सकता है:
void foo(bool flag);
...
int flag = TRUE;
foo(flag);
कुछ कंपाइलर int => बूल रूपांतरण के बारे में एक चेतावनी उत्पन्न करेंगे। कभी-कभी लोग ऐसा करने से बचते हैं:
foo(flag == TRUE);
C ++ बूल होने के लिए अभिव्यक्ति को मजबूर करने के लिए। लेकिन अगर आप # ट्राय करते हैं! FALSE, तो आप खत्म हो जाते हैं:
foo(flag == !0);
जो अंत-से-बूल तुलना करना समाप्त करता है जो किसी भी तरह चेतावनी को ट्रिगर कर सकता है।
यदि आप C99 का उपयोग कर रहे हैं तो आप _Bool
प्रकार का उपयोग कर सकते हैं । कोई #include
एस आवश्यक नहीं हैं। हालांकि, जहां आप एक पूर्णांक है जैसे कि यह इलाज करने की आवश्यकता है 1
है true
और 0
हैfalse
।
फिर आप को परिभाषित कर सकते TRUE
हैं और FALSE
।
_Bool this_is_a_Boolean_var = 1;
//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;
#include <stdbool.h>
और उपयोग bool
, true
और false
मानक आप के लिए करना चाहता है।
यही है वह जो मेरे द्वारा उपयोग किया जाता है:
enum {false, true};
typedef _Bool bool;
_Bool
सी में निर्मित प्रकार है। यह बूलियन मूल्यों के लिए अभिप्रेत है।
आप बस #define
निर्देश का उपयोग इस प्रकार कर सकते हैं:
#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;
और निम्नानुसार उपयोग करें:
bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);
और इसी तरह
arg
को एक पूरे के रूप में और अभिव्यक्ति के आसपास कोष्ठक द्वारा संरक्षित किया जाना चाहिए #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
:। हालांकि, यह झूठ के लिए परीक्षण करने के लिए बेहतर होगा (यह सही जवाब दे देंगे, भले ही arg
23 के बजाय 0 या 1 था: #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
लेकिन पूरे अभिव्यक्ति को कम किया जा सकता है। #define NOT(arg) (!(arg))
ज़ाहिर है, है, जो एक ही परिणाम पैदा करता है।