#define TRUE!FALSE vs #define TRUE 1
撇开自从c99以来stdbool.h
已经存在的事实,当定义宏来处理C
布尔类型时,以下是否有任何区别?
#define FALSE 0 #define TRUE 1 // Option 1 #define TRUE !FALSE // Option 2
从这里的实例来看 ,它似乎没有什么区别。 两种方案都有技术优势吗? (不包括第二个例子对c ++ bool
对象更好的事实。)
ISO C和C99都定义了!
像这样。
逻辑否定运算符的结果! 如果其操作数的值比较不等于0则为0;如果其操作数的值比较等于0则为1.结果的类型为int。 表达式!E等价于(0 == E)。
所以!0
评估为1
。 给定符合标准的C编译器 ,您的选项将具有相同的结果。 此外,没有运行时惩罚,编译器将在编译时不断折叠!0
到1
。
如果你想把它带到逻辑极端,不做任何关于真或假的假设……
#define TRUE (1==1) #define FALSE (!TRUE)
无论语言如何,这都具有始终如一的优点。 例如,在shell 0中通常被认为是“真”或“不是错误”。
从C没有达成一致意见的标准来看,这种事情是不合时宜的。 例如, Code Complete的第一版在第369页提倡这一点。当它在1993年发布时,你的C编译器很可能不符合ISO标准,并且stdbool.h不存在。 “代码完成”也适用于使用多种语言的多语言程序员。 有些像shell和Lisp,以不同的方式定义真理。
选项2没有任何好处,因为! 0
! 0
标准由C标准保证评估为1。
以这种方式定义TRUE
是旧资源的主要内容,可能是为了遵循风格指南,要求尽可能避免“魔法常数”。
差别不大。
#define TRUE 1
优于#define TRUE !FALSE
, 1
表示不受运算符优先级影响的单项。
!FALSE
可以(!FALSE)
来处理试图使用++ -- [] . ->
神秘代码++ -- [] . ->
++ -- [] . ->
,其优先级高于FALSE
。
#define FALSE 0 #define TRUE 1 // Option 1 #define TRUE !FALSE // Option 2
价值没有区别。 1
和!0
都是int
类型的常量表达式,具有相同的值1
(通过标准对!
运算符的语义的定义)。
第二个定义没有正确括号,可能存在差异。 请记住,宏扩展是以文本方式执行的。 在表达式中间展开未经表达的宏可能会导致运算符优先级问题。 我在这里写了一个人为的例子。
自一元以来!
运算符具有非常高的优先级,您不太可能遇到问题。 我能想到的唯一情况是你是否将它用作索引操作符的前缀。 例如,给定:
int arr[] = { 10, 20 };
选项1给出:
TRUE[arr] == 20
而选项2给出:
TRUE[arr] == 0
要了解原因,请记住数组索引是可交换的(请参阅此问题和我的答案 ,并且索引运算符[]
绑定比!
这里的课程是:
-
对于任何打算用作表达式的宏,整个宏定义应该括在括号中 – 即使你不能想到它会重要的情况。
-
把事情简单化。 在C中,
0
是唯一的假值,1
是规范的真值。 (任何非零值都是“true”,但内置的“布尔”运算符总是产生0
或1
)使用!
运算符以FALSE
定义TRUE
(反之亦然)只是一种不必要的复杂化。
如果可以,请使用
。 如果你不能(因为你坚持使用前C99编译器),我推荐这个:
typedef enum { false, true } bool;
它与C99的_Bool
/ bool
不完全相同(对此bool
类型的转换未归一化为0
或1
),但它几乎适用于所有目的。
在C语言中,TRUE被正确定义为(!FALSE),因为当零(0)为FALSE且FALSE为零(0)时, 任何其他值为 TRUE。 您几乎可以将任何变量用作布尔表达式,如果它不为零,则表达式的值为TRUE。 出于这个原因,NULL指针为零。 字符串结尾字符(’\ 0’)也是如此。 编写了大量代码来利用这一事实。 考虑:
while ( *d++ = *s++ );
复制将在复制字符串结尾字符时结束。 这个成语很常见。 别介意缓冲区大小问题。
如果没有现代专用布尔类型,其中唯一可能的值为TRUE和FALSE,那么测试相等为TRUE是一个坏主意的原因之一。 为了安全起见,我建议你养成一个习惯,以便在不平等的情况下测试不平等。 你可能并不总是能够使用新的和有光泽的。
他们是一样的。
-
!0
是1
所以!FALSE
是1
#define TRUE !FALSE
完全没有技术优势,虽然它一直存在并出现在很多地方。
#define TRUE !FALSE
可能会被误解,可以认为TRUE
代表的每个值都不是0
。
- 只有
1
等于TRUE
,其他值如255
……(其中!=0
)不等于TRUE
为了防止这种误解 ,许多组织要求不要使用#define TRUE !FALSE
不再或者与TRUE
比较应该更改为!FALSE
:
// Should not if (var_bool == TRUE) { ... } //Should if (var_bool != FALSE) { ... }