मैंने सी में परिभाषाएँ देखी हैं
#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)ट्रिक TRUEC के पारदर्शी होने के तरीके के लिए उपयोगी है, फिर भी 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 ++ कंपाइलर के नैदानिक राय से लाभ उठा सकते हैं।
TRUEC ++ के अंतर्गत अलग-अलग होंगी।
#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 से लिया गया है )