我在编码书中看到了以下宏定义.
#define TRUE '/'/'/' #define FALSE '-'-'-'
那里没有解释.
请向我解释如何将这些作为工作TRUE
和FALSE
.
让我们看看:'/' / '/'
意味着char
文字/
,除以char
文字'/'
本身.结果是一个,这听起来很合理TRUE
.
并且'-' - '-'
意味着char
文字'-'
,从中减去.这是零(FALSE
).
这有两个问题:首先,它不可读.使用1
和0
绝对更好.另外,正如TartanLlama和KerrekSB所指出的那样,如果您打算使用该定义,请在它们周围添加括号,这样您就不会有任何意外:
#include#define TRUE '/'/'/' #define FALSE '-'-'-' int main() { printf ("%d\n", 2 * FALSE); return 0; }
这将打印char
文字的值'-'
(我系统上的45).
括号:
#define TRUE ('/'/'/') #define FALSE ('-'-'-')
程序正确地打印为零,即使将真值乘以整数没有多大意义,但它只是一个例子,如果你没有用括号表示你的宏可能会咬你.
这只是另一种写作方式
#define TRUE 1 #define FALSE 0
表达式'/'/'/'
将自己划分char值,'/'
结果为1.
表达式'-'-'-'
将减去'-'
自身的char值,结果为0.
但是整个define
表达式周围的括号丢失了,这可能导致使用这些宏的代码出错.杰伊的回答很好地说明了这一点.
忘记括号可能有害的"现实"场景的一个例子是将这些宏与C风格的强制转换操作符结合使用.如果有人决定将这些表达式转换bool
为C++,例如:
#include#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 ('-'-'-')
与其他更高优先级的运算符一起使用时,避免意外更改值.
杰伊已经回答了为什么这些表达的价值是0
和 1
.
由于历史原因,这些表达式'/'/'/'
和'-'-'-'
来自的条目之一在1984年第一次国际C语言混乱代码大赛:
int i;main(){for(;i["](链接到这里的程序,有一个暗示这个程序在上面的IOCCC页面中做了什么.)
此外,如果我没记错这些表达式作为混淆宏,
TRUE
并且FALSE
也被Don Libes(1993)的"混淆C和其他奥秘"一书中所述.
5> anand..:为
True
和写宏的热闹方式False
.已经提供
/
了许多解释意味着一个1字节的数字(按照ASCII),当它除以它时,它会给你1
哪个将被视为True
同样-
又是一个字节数,当减去它给你的相同值时0
将被解释为false
#define TRUE '/'/'/' #define FALSE '-'-'-'因此我们可以替换
/
或-
使用我们喜欢的任何字符,例如:#define TRUE '!'/'!' #define FALSE 'o'-'o'将保持与原始表达式相同的含义.
6> Fabien..:让我们从真实开始吧.您可以将其读作
'/' / '/'
,这意味着"字符'/'除以字符'/'".由于C中的每个字符都是一个数值(在一个字节上),因此可以将其读作"字符的ASCII值'/'除以相同字符的ASCII值",这意味着1(因为很明显, x/x是1).因此,TRUE
是1.因为
FALSE
,它的原因相同:'-'-'-'
读取'-' - '-'
,即" - '的ASCII值减去' - ''的ASCII值,即为0.因此,FALSE
为0.这是一个令人讨厌的方式来说明显而易见的.
这与ASCII无关.
@Fabien:它不依赖于ASCII.`'/'/'/'`对于*any*有效字符集是1,无论是''/'== 47`(因为它是ASCII),或''/'== 97`(因为它在EBCDIC)或任何其他价值.
@Pawel:符合C的实现不能将`'/''映射到'0`.该值保留给null字符.
@ Matheus208如果帕维尔迂腐,那就是(' - ' - ' - '),因为他的观点基于一个未说明的条件; 将基思的言论描述为迂腐可能更多('/'/'/'),但我称之为"澄清"(并且添加的笑脸"迂腐"对我来说肯定是'/' - '/'.可能是(' - '/' - ')这些评论可以被称为迂腐,但是,1)在这个领域不是有点强制性的吗?2)他们让我思考; 3)我对某些事情比我更清楚.是的,我想我自己就是迂腐!(但我对"迂腐"的含义比我更清楚!;-)
你是迂腐的.