TRUE 和 FALSE 宏的奇怪定义
Strange definitions of TRUE and FALSE macros
我在编码书上看到了下面的宏定义。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
那里没有解释。
请向我解释一下 TRUE
和 FALSE
是如何工作的。
只是另一种写法
#define TRUE 1
#define FALSE 0
表达式'/'/'/'
将'/'
的char值除以自身,结果为1。
表达式 '-'-'-'
将从自身中减去 '-'
的字符值,结果为 0。
整个 define
表达式周围的括号丢失了,这可能会导致使用这些宏的代码出错。 很好地解决了这个问题。
忘记括号可能有害的 "real-life" 场景的一个示例是将这些宏与 C 风格的强制转换运算符结合使用。例如,如果有人决定将这些表达式转换为 C++ 中的 bool
:
#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
。
相当于写作
#define TRUE 1
#define FALSE 0
表达式'/'/'/'
实际上做的是将字符/
(无论它的数值是什么)除以自身,所以它变成1
。
类似地,表达式 '-'-'-'
从自身减去字符 -
并求得 0
.
最好写成
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
避免在与其他优先级更高的运算符一起使用时意外更改值。
让我们看看:'/' / '/'
表示 char
文字 /
除以 char
文字 '/'
本身。结果是 1,这对于 TRUE
.
来说是合理的
而 '-' - '-'
表示 char
文字 '-'
,从自身中减去。这是零 (FALSE
)。
这有两个问题:首先,它不可读。使用 1
和 0
绝对更好。此外,正如 TartanLlama 和 KerrekSB 指出的那样,如果您要使用该定义,请务必在它们周围添加括号,这样您就不会感到意外:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
这将打印 char
文字 '-'
的值(在我的系统上为 45)。
带括号:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
程序正确地打印了零,即使将真值乘以整数没有多大意义,但这只是那种如果你不加括号可能会咬你的意想不到的错误的一个例子你的宏。
让我们从真实开始。你可以读作'/' / '/'
,意思是"character '/' divided by character '/'"。因为在 C 中,每个字符都是一个数值(在一个字节上),它可以读作 "the ASCII value of character '/' divided by the ASCII value of that same character",意思是 1(因为,很明显,x/x 是 1)。因此,TRUE
是 1。
对于FALSE
,同理:'-'-'-'
读作'-' - '-'
,即"the ASCII value of '-' minus the ASCII value of '-'",即0。因此,FALSE
为0。
这是一种令人讨厌的陈述显而易见的方式。
已经回答了为什么这些表达式的值是 0
和 1
.
出于历史原因,这些表达式 '/'/'/'
和 '-'-'-'
来自 1st International Obfuscated C Code Contest in 1984 的条目之一:
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);}
(Link 到程序 here,在上面的 IOCCC 页面中有提示这个程序做了什么。)
此外,如果我没记错的话,这些表达式作为 TRUE
和 FALSE
的混淆宏也包含在 Don Libes (1993) 的 "Obfuscated C and Other Mysteries" 书中。
这是为 True
和 False
编写宏的一种搞笑方式。
已经提供了很多解释 /
表示一个 1 字节的数字(按照 ASCII)除以它自己时它给你 1
将被视为 True
并且同样,-
再次是一个字节数,减去它给你的相同值 0
将被解释为 false
#define TRUE '/'/'/'
#define FALSE '-'-'-'
因此我们可以用我们喜欢的任何字符替换 /
或 -
,例如:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
将保持与原始表达式相同的含义。
我在编码书上看到了下面的宏定义。
#define TRUE '/'/'/'
#define FALSE '-'-'-'
那里没有解释。
请向我解释一下 TRUE
和 FALSE
是如何工作的。
只是另一种写法
#define TRUE 1
#define FALSE 0
表达式'/'/'/'
将'/'
的char值除以自身,结果为1。
表达式 '-'-'-'
将从自身中减去 '-'
的字符值,结果为 0。
整个 define
表达式周围的括号丢失了,这可能会导致使用这些宏的代码出错。
忘记括号可能有害的 "real-life" 场景的一个示例是将这些宏与 C 风格的强制转换运算符结合使用。例如,如果有人决定将这些表达式转换为 C++ 中的 bool
:
#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
。
相当于写作
#define TRUE 1
#define FALSE 0
表达式'/'/'/'
实际上做的是将字符/
(无论它的数值是什么)除以自身,所以它变成1
。
类似地,表达式 '-'-'-'
从自身减去字符 -
并求得 0
.
最好写成
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
避免在与其他优先级更高的运算符一起使用时意外更改值。
让我们看看:'/' / '/'
表示 char
文字 /
除以 char
文字 '/'
本身。结果是 1,这对于 TRUE
.
而 '-' - '-'
表示 char
文字 '-'
,从自身中减去。这是零 (FALSE
)。
这有两个问题:首先,它不可读。使用 1
和 0
绝对更好。此外,正如 TartanLlama 和 KerrekSB 指出的那样,如果您要使用该定义,请务必在它们周围添加括号,这样您就不会感到意外:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
这将打印 char
文字 '-'
的值(在我的系统上为 45)。
带括号:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
程序正确地打印了零,即使将真值乘以整数没有多大意义,但这只是那种如果你不加括号可能会咬你的意想不到的错误的一个例子你的宏。
让我们从真实开始。你可以读作'/' / '/'
,意思是"character '/' divided by character '/'"。因为在 C 中,每个字符都是一个数值(在一个字节上),它可以读作 "the ASCII value of character '/' divided by the ASCII value of that same character",意思是 1(因为,很明显,x/x 是 1)。因此,TRUE
是 1。
对于FALSE
,同理:'-'-'-'
读作'-' - '-'
,即"the ASCII value of '-' minus the ASCII value of '-'",即0。因此,FALSE
为0。
这是一种令人讨厌的陈述显而易见的方式。
0
和 1
.
出于历史原因,这些表达式 '/'/'/'
和 '-'-'-'
来自 1st International Obfuscated C Code Contest in 1984 的条目之一:
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);}
(Link 到程序 here,在上面的 IOCCC 页面中有提示这个程序做了什么。)
此外,如果我没记错的话,这些表达式作为 TRUE
和 FALSE
的混淆宏也包含在 Don Libes (1993) 的 "Obfuscated C and Other Mysteries" 书中。
这是为 True
和 False
编写宏的一种搞笑方式。
已经提供了很多解释 /
表示一个 1 字节的数字(按照 ASCII)除以它自己时它给你 1
将被视为 True
并且同样,-
再次是一个字节数,减去它给你的相同值 0
将被解释为 false
#define TRUE '/'/'/'
#define FALSE '-'-'-'
因此我们可以用我们喜欢的任何字符替换 /
或 -
,例如:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
将保持与原始表达式相同的含义。