TRUE और FALSE मैक्रोज़ की अजीब परिभाषाएँ


300

मैंने निम्नलिखित मैक्रो परिभाषाओं को एक कोडिंग पुस्तक में देखा है।

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

वहां कोई स्पष्टीकरण नहीं था।

कृपया मुझे समझा कि कैसे इन के रूप में काम करेंगे TRUEऔर FALSE


63
मुझे लगता है कि TRUE को 1 और FALSE को 0 के रूप में परिभाषित करने के लिए यह केवल एक मजेदार तरीका है
BlackDwarf

160
ध्यान दें कि यह उन भावों के आसपास कोष्ठक के बिना एक भयानक विचार है। मेरा मतलब है कि यह उनके साथ एक भयानक विचार है, लेकिन बिना आप सिर्फ डिबगिंग की एक लंबी रात के लिए पूछ रहे हैं।
तर्तनलमा

70
क्या मुझे पता है कि आप जिस कोडिंग पुस्तक का संदर्भ दे रहे हैं?
आर्टम

47
मुझे उम्मीद है कि पुस्तक ने इसे खराब या जानबूझकर अस्पष्ट कोड के उदाहरण के रूप में शामिल किया है।
जॉन हैना

31
@ डैनियल: एक और विचार रैंड के लिए होगा ()% 2 मेंड को रैंड () 2% के रूप में परिभाषित करता है, इसलिए यह कभी-कभी == सही है और कभी कभी == FALSE।
कैसरलूडी

जवाबों:


380

चलो देखते हैं: '/' / '/'साधन charशाब्दिक /, से विभाजित charशाब्दिक '/'ही। परिणाम एक है, जो उचित लगता है TRUE

और शाब्दिक '-' - '-'अर्थ है , स्वयं से घटाया हुआ। यह शून्य ( ) है।char'-'FALSE

इसके साथ दो समस्याएं हैं: पहला, यह पठनीय नहीं है। का उपयोग करना 1और 0बिल्कुल बेहतर है। इसके अलावा, जैसा कि टार्टनलामा और केरेकेएसबी ने बताया है, यदि आप कभी भी उस परिभाषा का उपयोग करने जा रहे हैं, तो कृपया उनके चारों ओर कोष्ठक जोड़ें, ताकि आपको कोई आश्चर्य न हो:

#include <stdio.h>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
        printf ("%d\n", 2 * FALSE);
        return 0;
}

यह charशाब्दिक '-'(मेरे सिस्टम पर 45) के मूल्य को प्रिंट करेगा ।

कोष्ठक के साथ:

#define TRUE  ('/'/'/')
#define FALSE ('-'-'-')

कार्यक्रम सही ढंग से शून्य प्रिंट करता है, भले ही यह एक पूर्णांक द्वारा एक सत्य मूल्य को गुणा करने के लिए बहुत अधिक समझ में नहीं आता है, लेकिन यह सिर्फ उस तरह के अप्रत्याशित कीड़े का एक उदाहरण है जो आपको अपने मैक्रोज़ को छोटा नहीं करने पर काट सकता है।


6
धिक्कार है कि मैं इसे समझने के लिए बहुत कुछ ले गया: यह भी सोचा कि यह एक अजीब बात है क्योंकि यह ग्लिफ़ है ... एक्सडी नहीं जानता
लुइस मूसली

8
यह वास्तव में सत्य मूल्य के साथ गुणा करने के लिए समझ में आता है। टेस्ट इंडेंटेशन के लिए * should_indent का परिणाम या तो होगा या इंडेंटेशन इस आधार पर होगा कि क्या should_indent बिना ब्रांचिंग के है। (मुझे लगता है कि यह खराब उदाहरण है, जब टेक्स्ट सिंगल ब्रांचिंग के साथ काम करना कोई मायने नहीं रखता है, (मैंने इस तकनीक को शेडर्स में और एक्सपीएटीएच में देखा है (दोनों बहुत अलग हैं और मैं सटीक रूप से याद नहीं करता हूं)
अल्पार

2
अल्पेदर - लेकिन यह वैचारिक और शारीरिक रूप से ऐसा करने के लिए संवेदी नहीं है - इस मामले में यह पूर्णांक द्वारा ifगुणा करने के बजाय स्पष्ट (और वैचारिक रूप से समझ में आने वाला) होगा TRUE
Jay

4
महान व्याख्या। सोने का बिल्ला है!
माइकल हैम्पटन

2
तार्किक नकार को लागू किया जा सकता है notx = TRUE- x;और ठीक काम करता है। सिवाय इसके कि TRUE-FALSE-44 (ASCII को मानते हुए)
हेगन वॉन एटिजन

89

यह लिखने का एक और तरीका है

#define TRUE 1
#define FALSE 0

अभिव्यक्ति स्वयं '/'/'/'के चार मूल्य को विभाजित करेगी '/', जो परिणाम के रूप में 1 देगी।

अभिव्यक्ति स्वयं '-'-'-'के चार मूल्य को बदल '-'देगी, जो परिणाम के रूप में 0 देगा।

संपूर्ण defineअभिव्यक्तियों के आसपास की ब्रैकेट गायब हैं, हालांकि, इन मैक्रोज़ का उपयोग करके कोड में त्रुटियां हो सकती हैं। जय का जवाब बहुत अच्छी तरह से मानता है।

"वास्तविक जीवन" परिदृश्य का एक उदाहरण जहां कोष्ठक को भूल जाना हानिकारक हो सकता है, सी-स्टाइल ऑपरेटर के साथ इन मैक्रोज़ का संयुक्त उपयोग। अगर कोई boolउदाहरण के लिए C ++ में इन भावों को डालने का फैसला करता है :

#include <iostream>

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

int main() {
    std::cout << "True: " << (bool) TRUE << std::endl;
    std::cout << "False: " << (bool) FALSE << std::endl;
    return 0;
}

यहाँ हमें क्या मिलता है:

True: 0
False: -44

तो (bool) TRUEवास्तव में मूल्यांकन करेगा false, और (bool) FALSEमूल्यांकन करेगा true


4
इसका उदाहरण एक अच्छा है :)
किट फिस्टो

44

यह लिखने के बराबर है

#define TRUE 1
#define FALSE 0

'/'/'/'वास्तव में जो अभिव्यक्ति करता है वह चरित्र को विभाजित करता है /(जो भी इसका संख्यात्मक मान है), इसलिए यह बन जाता है 1

इसी तरह, अभिव्यक्ति '-'-'-'चरित्र -को खुद से घटाती है और उसका मूल्यांकन करती है 0

लिखना बेहतर होगा

#define TRUE ('/'/'/')
#define FALSE ('-'-'-')

अन्य उच्च-पूर्वता ऑपरेटरों के साथ उपयोग किए जाने पर मूल्यों के आकस्मिक परिवर्तन से बचने के लिए।


5
जबरदस्त हंसी! इसीलिए मैक्रों का उचित रूप से पालन-पोषण होना चाहिए।
0605002

एक गोले पर 3 अधिकार और आप एक ही स्थान पर समाप्त होते हैं
डेरेक 功夫 a

@KerrekSB नहीं, लेकिन तीन लेफ़्ट करते हैं :)
टिम लॉन्ग

33

जे पहले से ही उत्तर क्यों इन भाव के मूल्यों हैं 0और 1

इतिहास के लिए, ये अभिव्यक्तियाँ '/'/'/'और 1984 में 1 अंतर्राष्ट्रीय Obfuscated C कोड प्रतियोगिता'-'-'-' की प्रविष्टियों में से एक हैं :

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

( यहां कार्यक्रम से लिंक करें , ऊपर आईओसीसीसीसी पृष्ठ में यह कार्यक्रम क्या करता है, इसका एक संकेत है।)

इसके अलावा, अगर मैं के लिए समझ से परे मैक्रो के रूप में इन सही ढंग से भाव याद TRUEऔर FALSEभी कवर किया गया "अस्पष्ट सी और अन्य रहस्यों" डॉन लाइब्स (1993) द्वारा पुस्तक।


7

यह Trueऔर के लिए मैक्रोज़ लिखने के लिए प्रफुल्लित करने वाला तरीका है False

जैसा कि कई स्पष्टीकरण प्रदान किए गए हैं, /एक 1 बाइट संख्या (एएससीआईआई के अनुसार) का अर्थ है जब स्वयं द्वारा विभाजित किया जाता है 1जो आपको दिया जाएगा Trueऔर इसी तरह -फिर से एक बाइट नंबर है, जब उसी मूल्य को घटाया जाता है 0जो आपको देता है जिसकी व्याख्या की जाएगीfalse

#define TRUE  '/'/'/'
#define FALSE '-'-'-'

इसलिए हम उदाहरण के लिए किसी भी चार्ट को बदल सकते हैं /या उसके -साथ कर सकते हैं :

#define TRUE  '!'/'!'
#define FALSE 'o'-'o'

मूल अभिव्यक्ति के समान ही अर्थ रखेंगे।


6

चलो सच के साथ शुरू करते हैं। आप इसे पढ़ सकते हैं '/' / '/', जिसका अर्थ है "वर्ण" / 'वर्ण से विभाजित "/'। चूंकि प्रत्येक वर्ण, C में, एक संख्यात्मक मान है (एक बाइट पर), इसे "उसी चरित्र के ASCII मान से विभाजित" / "ASCII वर्ण का मान" के रूप में पढ़ा जा सकता है, जिसका अर्थ है 1 (क्योंकि, जाहिर है,) x / x 1) है। इसलिए, TRUE1 है।

इसके लिए FALSE, इसका एक ही तर्क है: '-'-'-'पढ़ता है '-' - '-', जिसका अर्थ है "- 'का ASCII मान' - 'का ASCII मान' -", जो 0. है, इसलिए FALSE0 है।

यह स्पष्ट रूप से बताने का एक बुरा तरीका है।


7
इसका ASCII से कोई लेना-देना नहीं है।
केरेक एसबी

6
@ फैबियन: यह ASCII पर निर्भर नहीं करता है। किसी भी मान्य वर्ण सेट के '/'/'/'लिए 1 है , चाहे वह (ASCII में हो), या (जैसा कि EBCDIC में है), या कोई अन्य मूल्य। '/' == 47'/' == 97
कीथ थॉम्पसन

4
@Pawel: एक अनुरूप सी कार्यान्वयन के '/'लिए मैप नहीं किया जा सकता है 0। यह मान अशक्त वर्ण के लिए आरक्षित है।
कीथ थॉम्पसन

2
आप पांडित्यपूर्ण हो रहे हैं।
Matheus208

3
@ Matheus208 यदि पावेल को पांडित्य हो रहा था, तो वह ('-'-'-') क्योंकि उनकी बात एक अस्थिर स्थिति पर आधारित थी; कीथ की टिप्पणियों को पांडित्य के रूप में वर्णित करना अधिक हो सकता है ('/' / '/'), लेकिन मैं उन्हें "स्पष्ट करना" कहूंगा (और जोड़े गए स्माइली के साथ "पांडित्य" निश्चित रूप से मुझे '/' - '/' लगता है)। यह ('-' / '-') हो सकता है कि एक साथ ली गई टिप्पणियों को पांडित्य कहा जा सकता है लेकिन, 1) क्या यह इस क्षेत्र में कुछ अनिवार्य नहीं है? 2) उन्होंने मुझे सोचा; और 3) मैं कुछ चीजों से थोड़ा साफ हूं। और हाँ, मुझे लगता है कि मैं खुद पांडित्यपूर्ण हो रहा हूँ! (लेकिन मैं स्पष्ट रूप से "पांडित्य" का अर्थ है कि मैं क्या कर रहा था!) ​​;-)
Zhora
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.