मैंने सी में परिभाषाएँ देखी हैं
#define TRUE (1==1)
#define FALSE (!TRUE)
क्या यह आवश्यक है? केवल TRUE को 1 के रूप में परिभाषित करने और 0 के रूप में FALSE पर क्या लाभ है?
मैंने सी में परिभाषाएँ देखी हैं
#define TRUE (1==1)
#define FALSE (!TRUE)
क्या यह आवश्यक है? केवल TRUE को 1 के रूप में परिभाषित करने और 0 के रूप में FALSE पर क्या लाभ है?
जवाबों:
यदि संकलक इसका समर्थन करता है तो यह दृष्टिकोण वास्तविक boolean
प्रकार (और संकल्प true
और false
) का उपयोग करेगा। (विशेष रूप से, C ++)
हालांकि, यह जांचना बेहतर होगा कि क्या C ++ उपयोग में है ( __cplusplus
मैक्रो के माध्यम से ) और वास्तव में उपयोग करें true
और false
।
एक सी कंपाइलर में, यह 0
और के बराबर है 1
।
(ध्यान दें कि कोष्ठक हटाने से संचालन के क्रम के कारण टूट जाएगा)
1==1
है int
। (देखें stackoverflow.com/questions/7687403/… ।)
boolean
प्रकार के साथ ?
true
या false
।
#define TRUE true
और #define FALSE false
जब भी __cplusplus
परिभाषित किया जाएगा।
उत्तर पोर्टेबिलिटी है। के संख्यात्मक मान TRUE
और FALSE
महत्वपूर्ण नहीं हैं। क्या है महत्वपूर्ण है की तरह एक बयान है कि if (1 < 2)
करने के लिए मूल्यांकन करता है if (TRUE)
और इस तरह के एक बयान if (1 > 2)
करने के लिए मूल्यांकन करता है if (FALSE)
।
सी में दी गई, का (1 < 2)
मूल्यांकन करता है 1
और (1 > 2)
मूल्यांकन करता है 0
, इसलिए जैसा कि दूसरों ने कहा है, जहां तक संकलक का संबंध है, कोई व्यावहारिक अंतर नहीं है। लेकिन संकलक को परिभाषित करने TRUE
और FALSE
अपने स्वयं के नियमों के अनुसार, आप प्रोग्रामर्स को उनके अर्थ स्पष्ट कर रहे हैं, और आप अपने कार्यक्रम और किसी भी अन्य पुस्तकालय में स्थिरता की गारंटी दे रहे हैं (अन्य पुस्तकालय मानकर सी मानकों का पालन करते हैं ... आप चौंकना)।
कुछ इतिहास
कुछ मूल बातें परिभाषित FALSE
के रूप में 0
और TRUE
के रूप में -1
। कई आधुनिक भाषाओं की तरह, उन्होंने किसी भी गैर-शून्य मान की व्याख्या कीTRUE
, लेकिन उन्होंने बूलियन अभिव्यक्तियों का मूल्यांकन किया जो कि सच थे -1
। उनके NOT
ऑपरेशन को 1 जोड़कर और संकेत को फ़्लिप करके लागू किया गया था, क्योंकि यह इस तरह से करना कुशल था। तो 'नॉट एक्स' बन गया -(x+1)
। इसका एक दुष्परिणाम यह है कि जैसे कोई मूल्य का 5
मूल्यांकन करता है TRUE
, बल्कि उसका NOT 5
मूल्यांकन करता है -6
, जो है भी TRUE
! इस तरह की बग ढूंढना मजेदार नहीं है।
उत्तम आचरण
को देखते हुए वास्तविक नियम है कि शून्य के रूप में व्याख्या की है FALSE
और किसी भी रूप में गैर-शून्य मान व्याख्या की है TRUE
, तो आप चाहिए करने के लिए बूलियन दिखने भाव की तुलना कभी नहीं TRUE
याFALSE
। उदाहरण:
if (thisValue == FALSE) // Don't do this!
if (thatValue == TRUE) // Or this!
if (otherValue != TRUE) // Whatever you do, don't do this!
क्यों? क्योंकि कई प्रोग्रामर int
एस के रूप में व्यवहार करने के शॉर्टकट का उपयोग करते हैं bool
। वे समान नहीं हैं, लेकिन कंपाइलर आमतौर पर इसकी अनुमति देते हैं। इसलिए, उदाहरण के लिए, यह लिखना पूरी तरह से कानूनी है
if (strcmp(yourString, myString) == TRUE) // Wrong!!!
यह वैध लगता है , और संकलक इसे खुशी से स्वीकार करेगा, लेकिन यह संभवतः वह नहीं करता है जो आप चाहते हैं। इसलिए कि वापसी का मूल्य strcmp()
है
० अगर yourString == myString
<० अगर yourString < myString
> ० अगरyourString > myString
तो ऊपर की लाइन TRUE
तभी लौटती है जब yourString > myString
।
ऐसा करने का सही तरीका या तो है
// Valid, but still treats int as bool.
if (strcmp(yourString, myString))
या
// Better: lingustically clear, compiler will optimize.
if (strcmp(yourString, myString) != 0)
इसी तरह:
if (someBoolValue == FALSE) // Redundant.
if (!someBoolValue) // Better.
return (x > 0) ? TRUE : FALSE; // You're fired.
return (x > 0); // Simpler, clearer, correct.
if (ptr == NULL) // Perfect: compares pointers.
if (!ptr) // Sleazy, but short and valid.
if (ptr == FALSE) // Whatisthisidonteven.
आपको अक्सर उत्पादन कोड में इन "खराब उदाहरणों" में से कुछ मिलेंगे, और कई अनुभवी प्रोग्रामर उनके द्वारा कसम खाते हैं: वे काम करते हैं, कुछ उनके (पेडेंटली?) सही विकल्पों की तुलना में कम हैं, और मुहावरों को लगभग सार्वभौमिक मान्यता प्राप्त है। लेकिन विचार करें: "सही" संस्करण कोई कम कुशल नहीं हैं, वे पोर्टेबल होने की गारंटी देते हैं, वे सख्त लिंटर भी पास करेंगे, और यहां तक कि नए प्रोग्रामर भी उन्हें समझेंगे।
क्या इसके लायक नहीं है?
(1==1)
से अधिक नहीं पोर्टेबल है 1
। संकलक के अपने नियम सी भाषा के हैं, जो समानता और संबंधपरक ऑपरेटरों के शब्दार्थ के बारे में स्पष्ट और स्पष्ट है। मैंने कभी नहीं देखा कि एक कंपाइलर को यह सामान गलत मिले।
strcmp
को तब कम, बराबर या उससे अधिक जाना जाता है। 0. यह -1, 0 या 1 होने की गारंटी नहीं है और जंगल में ऐसे प्लेटफार्म हैं जो कार्यान्वयन की गति हासिल करने के लिए उन मूल्यों को वापस नहीं करते हैं। तो अगर strcmp(a, b) == TRUE
तो a > b
लेकिन रिवर्स निहितार्थ पकड़ नहीं सकता है।
(1==1)
और मान के साथ 1
दोनों प्रकार के निरंतर भाव int
हैं। वे शब्दार्थ समान हैं। मुझे लगता है कि आप उस कोड को लिख सकते हैं जो पाठकों को पूरा करता है जो यह नहीं जानते, लेकिन यह कहां समाप्त होता है?
यह (1 == 1)
ट्रिक TRUE
C के पारदर्शी होने के तरीके के लिए उपयोगी है, फिर भी C ++ में बेहतर टाइपिंग प्रदान करती है। यदि आप "क्लीन सी" (जो या तो C या C ++ के रूप में संकलित हैं) या यदि आप एपीआई हेडर फाइल लिख रहे हैं जिसे C या C ++ प्रोग्रामर द्वारा उपयोग किया जा सकता है, तो उसी कोड को C या C ++ के रूप में व्याख्या किया जा सकता है।
C अनुवाद इकाइयों में, 1 == 1
इसका ठीक वही अर्थ है जो 1
; और 1 == 0
जैसा अर्थ है वैसा ही है 0
। हालाँकि, C ++ अनुवाद इकाइयों में, 1 == 1
प्रकार है bool
। तो TRUE
मैक्रो ने परिभाषित किया कि जिस तरह से सी ++ में बेहतर एकीकृत करता है।
यह कैसे बेहतर एकीकृत करता है इसका एक उदाहरण यह है कि उदाहरण के लिए यदि फ़ंक्शन के foo
लिए int
और bool
उसके बाद अधिभार है , तो अधिभार का foo(TRUE)
चयन करेगा bool
। तो TRUE
बस के रूप में परिभाषित किया गया है 1
, तो यह सी ++ में अच्छी तरह से काम नहीं करेगा। ओवरलोड foo(TRUE)
चाहते हैं int
।
बेशक, C99 पेश किया bool
, true
और false
और इन हेडर फाइल में इस्तेमाल किया जा सकता है कि C99 के साथ और सी के साथ काम
तथापि:
TRUE
और FALSE
के रूप में (0==0)
और (1==0)
पहले का C99।यदि आप मिश्रित C और C ++ प्रोजेक्ट में काम कर रहे हैं, और C99 नहीं चाहते हैं, तो निचले-मामले को परिभाषित करें true
, false
और bool
इसके बजाय।
#ifndef __cplusplus
typedef int bool;
#define true (0==0)
#define false (!true)
#endif
कहा जा रहा है, 0==0
चाल थी (है?) कुछ प्रोग्रामर द्वारा कोड में भी इस्तेमाल किया गया था जो किसी भी तरह से सी ++ के साथ हस्तक्षेप करने का कभी नहीं था। यह कुछ भी नहीं खरीदता है और सुझाव देता है कि प्रोग्रामर को गलतफहमी है कि सी में बुलियन कैसे काम करते हैं।
मामले में C ++ स्पष्टीकरण स्पष्ट नहीं था, यहाँ एक परीक्षण कार्यक्रम है:
#include <cstdio>
void foo(bool x)
{
std::puts("bool");
}
void foo(int x)
{
std::puts("int");
}
int main()
{
foo(1 == 1);
foo(1);
return 0;
}
उत्पादन:
bool
int
मिश्रित C और C ++ प्रोग्रामिंग के लिए प्रासंगिक ओवरलोड सी ++ फ़ंक्शन की टिप्पणियों से सवाल के रूप में। ये सिर्फ एक प्रकार का अंतर बताते हैं। स्वच्छ निदान के लिए C ++ के रूप में संकलित होने के लिए एक true
निरंतर होने की इच्छा के लिए एक वैध कारण bool
। यदि हम एक bool
पैरामीटर के रूप में पूर्णांक पास करते हैं, तो इसके उच्चतम चेतावनी स्तरों पर, C ++ कंपाइलर हमें रूपांतरण के बारे में चेतावनी दे सकता है । क्लीन सी में लिखने का एक कारण यह भी नहीं है कि हमारा कोड अधिक पोर्टेबल है (क्योंकि यह C ++ कंपाइलर द्वारा समझा जाता है, न केवल C कंपाइलर), लेकिन हम C ++ कंपाइलर के नैदानिक राय से लाभ उठा सकते हैं।
TRUE
C ++ के अंतर्गत अलग-अलग होंगी।
#ifdef __cplusplus
अपने इरादे को अधिक स्पष्ट रूप से व्यक्त करने के लिए उपयोग कर सकते हैं ।
bool
और int
व्यवहार में ज्यादा मायने नहीं रखती हैं, क्योंकि वे एक-दूसरे के लिए अनुमानित रूप से परिवर्तनीय हैं (और सी में वास्तव में "समान" , उद्धरण नोट करें , हालांकि) और ऐसी कई स्थितियाँ नहीं हैं जिनमें आपको वास्तव में दोनों के बीच की अवहेलना करने की आवश्यकता है । "बहुत ज्यादा नहीं" शायद बहुत भारी था, "खाकों और ओवरलोडिंग का उपयोग करने वाले कोड की तुलना में बहुत कम" शायद बेहतर होता।
#define TRUE (1==1)
#define FALSE (!TRUE)
के बराबर है
#define TRUE 1
#define FALSE 0
सी। में।
संबंधित ऑपरेटरों का परिणाम है 0
या 1
। 1==1
का मूल्यांकन करने की गारंटी है 1
और !(1==1)
इसका मूल्यांकन करने की गारंटी है 0
।
पहले रूप का उपयोग करने का कोई कारण नहीं है। ध्यान दें कि पहला रूप हालांकि कम कुशल नहीं है क्योंकि लगभग सभी संकलक पर एक स्थिर अभिव्यक्ति का मूल्यांकन रन-टाइम के बजाय संकलन समय पर किया जाता है। यह इस नियम के अनुसार अनुमत है:
(C99, 6.6p2) "रनटाइम के बजाय अनुवाद के दौरान एक निरंतर अभिव्यक्ति का मूल्यांकन किया जा सकता है, और तदनुसार किसी भी स्थान पर उपयोग किया जा सकता है जो एक स्थिर हो सकता है।"
यदि आप मैक्रो TRUE
और FALSE
मैक्रोज़ के लिए शाब्दिक उपयोग नहीं करते हैं, तो पीसी-लिंट भी एक संदेश (506, निरंतर मूल्य बूलियन) जारी करेगा।
सी के लिए,
TRUE
को परिभाषित किया जाना चाहिए1
। हालांकि, अन्य भाषाएं 1 के अलावा अन्य मात्राओं का उपयोग करती हैं इसलिए कुछ प्रोग्रामर को लगता है कि!0
यह सुरक्षित है।
इसके अलावा C99 में, stdbool.h
बूलियन मैक्रोज़ की परिभाषा true
और false
सीधे शाब्दिक उपयोग के लिए:
#define true 1
#define false 0
1==1
का मूल्यांकन करने की गारंटी है1
if(foo == true)
, जो केवल खराब अभ्यास से फ्लैट-आउट बग्गी तक जाएगा।
(x == TRUE)
तुलना में एक अलग सत्य मूल्य हो सकता है x
।
सी ++ (पहले से उल्लेख किया गया) के अलावा, एक और लाभ स्थिर विश्लेषण उपकरण के लिए है। संकलक किसी भी अक्षमता के साथ दूर करेगा, लेकिन एक स्थिर विश्लेषक तुलनात्मक परिणामों और अन्य पूर्णांक प्रकारों के बीच अंतर करने के लिए अपने स्वयं के सार प्रकारों का उपयोग कर सकता है, इसलिए यह स्पष्ट रूप से जानता है कि TRUE एक तुलना का परिणाम होना चाहिए और इसे संगत नहीं माना जाना चाहिए। एक पूर्णांक के साथ।
स्पष्ट रूप से सी का कहना है कि वे संगत हैं, लेकिन आप बग को उजागर करने में मदद करने के लिए उस सुविधा के जानबूझकर उपयोग को प्रतिबंधित करने का विकल्प चुन सकते हैं - उदाहरण के लिए, जहां किसी ने भ्रमित किया हो सकता है &
और &&
, या उन्होंने अपने ऑपरेटर की पूर्ववर्ती स्थिति को भुनाया है।
if (boolean_var == TRUE)
विस्तार के माध्यम से मूर्खतापूर्ण कोड भी पकड़ सकते हैं, if (boolean_var == (1 == 1))
जिसके लिए (1 == 1)
नोड की बढ़ी हुई प्रकार की जानकारी के लिए धन्यवाद पैटर्न में आता है if (<*> == <boolean_expr>)
।
व्यावहारिक अंतर कोई नहीं है। 0
का मूल्यांकन किया जाता है false
और 1
इसका मूल्यांकन किया जाता है true
। यह तथ्य कि आप बूलियन अभिव्यक्ति का उपयोग करते हैं ( 1 == 1
) या 1
, परिभाषित करने के लिए true
, कोई फर्क नहीं पड़ता है। इन दोनों का मूल्यांकन किया जाता है int
।
ध्यान दें कि सी मानक पुस्तकालय बूलियन को परिभाषित करने के लिए एक विशिष्ट हेडर प्रदान करता है stdbool.h
:।
true
का मूल्यांकन किया जाता है 1
और false
इसका मूल्यांकन किया जाता है 0
। C देशी बूलियन प्रकारों के बारे में नहीं जानता, वे सिर्फ ints हैं।
int
मूल्य के साथ 0
या प्रकार के परिणाम देते हैं 1
। सी में एक वास्तविक बूलियन प्रकार होता है ( _Bool
, जिसमें एक मैक्रो bool
परिभाषित होता है <stdbool.h>
, लेकिन इसे केवल C99 में जोड़ा गया था, जिसने नए प्रकार का उपयोग करने के लिए ऑपरेटरों के शब्दार्थ को नहीं बदला।
_Bool
, और <stdbool.h>
है #define bool _Bool
।
1 == 1
रूप में मूल्यांकन किया जा रहा है के बारे में सही हैं int
। संपादित।
हमें सही मूल्य नहीं पता है कि TRUE के बराबर है और संकलक की अपनी परिभाषा हो सकती है। तो क्या आप निजी तौर पर संकलक की परिभाषा के लिए आंतरिक का उपयोग करना है। यह हमेशा आवश्यक नहीं है यदि आपके पास अच्छी प्रोग्रामिंग आदतें हैं लेकिन कुछ खराब कोडिंग शैली की समस्याओं से बच सकते हैं, उदाहरण के लिए:
यदि ((a> b) == TRUE)
यह एक आपदा हो सकती है यदि आप TRUE को मैन्युअल रूप से 1 के रूप में परिभाषित करते हैं, जबकि TRUE का आंतरिक मूल्य एक और है।
>
ऑपरेटर हमेशा सच के लिए 1, झूठ के लिए 0 देता है। किसी भी सी कंपाइलर के इस गलत होने की कोई संभावना नहीं है। समानता की तुलना TRUE
और FALSE
घटिया शैली है; ऊपर स्पष्ट रूप से लिखा गया है if (a > b)
। लेकिन विचार है कि अलग सी संकलक सच्चाई का इलाज कर सकते हैं और गलत तरीके से गलत है।
आमतौर पर C प्रोग्रामिंग लैंग्वेज में 1 को सही और 0 को गलत के रूप में परिभाषित किया गया है। इसलिए आप निम्नलिखित अक्सर देखते हैं:
#define TRUE 1
#define FALSE 0
हालाँकि, 0 के बराबर किसी भी संख्या का मूल्यांकन सही और सशर्त विवरण में नहीं किया जाएगा। इसलिए नीचे का उपयोग करके:
#define TRUE (1==1)
#define FALSE (!TRUE)
आप केवल स्पष्ट रूप से दिखा सकते हैं कि जो कुछ भी सच नहीं है, उसे आप झूठे बनाकर सुरक्षित चलाने की कोशिश कर रहे हैं।
#define TRUE (’/’/’/’)
:;#define FALSE (’-’-’-’)
( कोडिंग-guidelines.com/cbook/cbook1_1.pdf पृष्ठ 871 से लिया गया है )