Kes*_* GN 297 c c++ macros obfuscation boolean
我在编码书中看到了以下宏定义.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Run Code Online (Sandbox Code Playgroud)
那里没有解释.
请向我解释如何将这些作为工作TRUE和FALSE.
Jay*_*Jay 379
让我们看看:'/' / '/'意味着char文字/,除以char文字'/'本身.结果是一个,这听起来很合理TRUE.
并且'-' - '-'意味着char文字'-',从中减去.这是零(FALSE).
这有两个问题:首先,它不可读.使用1和0绝对更好.另外,正如TartanLlama和KerrekSB所指出的那样,如果您打算使用该定义,请在它们周围添加括号,这样您就不会有任何意外:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将打印char文字的值'-'(我系统上的45).
括号:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
Run Code Online (Sandbox Code Playgroud)
程序正确地打印为零,即使将真值乘以整数没有多大意义,但它只是一个例子,如果你没有用括号表示你的宏可能会咬你.
Bla*_*arf 89
这只是另一种写作方式
#define TRUE 1
#define FALSE 0
Run Code Online (Sandbox Code Playgroud)
表达式'/'/'/'将自己划分char值,'/'结果为1.
表达式'-'-'-'将减去'-'自身的char值,结果为0.
但是整个define表达式周围的括号丢失了,这可能导致使用这些宏的代码出错.杰伊的回答很好地说明了这一点.
忘记括号可能有害的"现实"场景的一个例子是将这些宏与C风格的强制转换操作符结合使用.如果有人决定将这些表达式转换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;
}
Run Code Online (Sandbox Code Playgroud)
这是我们得到的:
True: 0
False: -44
Run Code Online (Sandbox Code Playgroud)
所以(bool) TRUE实际上会评估false,(bool) FALSE并将评估true.
060*_*002 44
它相当于写作
#define TRUE 1
#define FALSE 0
Run Code Online (Sandbox Code Playgroud)
表达式'/'/'/'实际上做的是将字符/(无论其数值是什么)单独划分,因此它变为1.
类似地,表达式从自身中'-'-'-'减去字符-并计算结果0.
写作会更好
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
Run Code Online (Sandbox Code Playgroud)
与其他更高优先级的运算符一起使用时,避免意外更改值.
oua*_*uah 33
杰伊已经回答了为什么这些表达的价值是0和 1.
由于历史原因,这些表达式'/'/'/'和'-'-'-'来自的条目之一在1984年第一次国际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);}
Run Code Online (Sandbox Code Playgroud)
(链接到这里的程序,有一个暗示这个程序在上面的IOCCC页面中做了什么.)
此外,如果我没记错这些表达式作为混淆宏,TRUE并且FALSE也被Don Libes(1993)的"混淆C和其他奥秘"一书中所述.
为True和写宏的热闹方式False.
已经提供/了许多解释意味着一个1字节的数字(按照ASCII),当它除以它时,它会给你1哪个将被视为True同样 -又是一个字节数,当减去它给你的相同值时0将被解释为false
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Run Code Online (Sandbox Code Playgroud)
因此我们可以替换/或-使用我们喜欢的任何字符,例如:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
Run Code Online (Sandbox Code Playgroud)
将保持与原始表达式相同的含义.
让我们从真实开始吧.您可以将其读作'/' / '/',这意味着"字符'/'除以字符'/'".由于C中的每个字符都是一个数值(在一个字节上),因此可以将其读作"字符的ASCII值'/'除以相同字符的ASCII值",这意味着1(因为很明显, x/x是1).因此,TRUE是1.
因为FALSE,它的原因相同:'-'-'-'读取'-' - '-',即" - '的ASCII值减去' - ''的ASCII值,即为0.因此,FALSE为0.
这是一个令人讨厌的方式来说明显而易见的.