[英]#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 中通常被认为是“true”或“not an error”。
在 C 没有达成一致的标准的时候,这种事情是不合时宜的。 例如, Code Complete 的第一版在第 369 页提倡这一点。当它于 1993 年发布时,您的 C 编译器很可能不符合 ISO 标准并且 stdbool.h 不存在。 “代码完成”也适用于使用多种不同语言的多语言程序员。 有些,比如 shell 和 Lisp,对真理的定义不同。
选项 2 没有任何好处,因为! 0
C 标准保证! 0
计算结果为 1。
以这种方式定义TRUE
是旧资料的主要内容,大概是为了遵循风格指南,该指南要求尽可能避免“魔法常数”。
#define FALSE 0
#define TRUE 1 // Option 1
#define TRUE !FALSE // Option 2
值没有区别。 1
和!0
都是具有相同值1
int
类型的常量表达式(根据标准对!
运算符语义的定义)。
可能的区别在于第二个定义没有正确加上括号。 请记住,宏扩展是以文本方式执行的。 在表达式中间扩展一个没有括号的宏会导致运算符优先级问题。 我在这里写了一个人为的例子。
自从一元!
运算符具有非常高的优先级,您不太可能遇到问题。 我能想到的唯一情况是,如果您将它用作索引运算符的前缀。 例如,给定:
int arr[] = { 10, 20 };
选项 1 给出:
TRUE[arr] == 20
而选项 2 给出:
TRUE[arr] == 0
要了解原因,请记住数组索引是可交换的(请参阅此问题和我的回答,并且索引运算符[]
绑定比!
更紧密。
这里的教训是:
对于任何打算用作表达式的宏,整个宏定义都应该括在括号中——即使您想不出有什么重要的情况。
把事情简单化。 在 C 中, 0
是唯一的假值, 1
是规范的真值。 (任何非零值都是“真”,但内置的“布尔”运算符总是产生0
或1
。)使用!
运算符将TRUE
定义为FALSE
(反之亦然)只是一种不必要的复杂化。
如果可以,请使用<stdbool.h>
。 如果你不能(因为你坚持使用 C99 之前的编译器),我建议这样做:
typedef enum { false, true } bool;
它与 C99 的_Bool
/ bool
不太一样(转换到这种bool
类型没有标准化为0
或1
),但它几乎可以满足所有用途。
差别不大。
#define TRUE 1
比#define TRUE !FALSE
略有优势,因为1
是不受运算符优先级影响的单个项目。
!FALSE
可以是(!FALSE)
来处理试图使用++ -- [] . ->
神秘代码++ -- [] . ->
++ -- [] . ->
,在FALSE
旁边有更高的优先级。
在 C 语言中,TRUE 被正确定义为 (!FALSE),因为零 (0) 是 FALSE,FALSE 是零 (0),任何其他值都是 TRUE。 您几乎可以将任何变量用作布尔表达式,如果它不为零,则表达式的值为 TRUE。 正是因为这个原因,NULL 指针为零。 字符串结尾字符 ('\\0') 也是如此。 已经编写了大量代码来利用这一事实。 考虑:
while ( *d++ = *s++ );
当字符串结束字符被复制时,复制将结束。 这个成语很常见。 别介意缓冲区大小问题。
这就是为什么如果您没有现代专用布尔类型(其中唯一可能的值是 TRUE 和 FALSE),则测试是否等于 TRUE 是一个坏主意的原因之一。 无论如何,为了安全起见,我建议你养成测试不等式为 FALSE 的习惯。 您可能并不总是能够使用新的和闪亮的。
没有太大区别。 但我认为#define TRUE 1
更好。
如果您使用#define TRUE !FALSE
:
FALSE
是 0, TRUE
是所有数字都期望为 0。
如果您使用#define TRUE 1
:
FALSE
为 0, TRUE
为 1。没问题。
他们只是一样。
!0
是1
所以!FALSE
是1
#define TRUE !FALSE
根本没有技术优势,尽管它存在很长时间并且出现在很多地方。
#define TRUE !FALSE
可能会被误解,人们可能认为TRUE
代表每个不是0
值。
1
等于TRUE
,其他值如2
、 3
、 255
...(其中!=0
)不等于TRUE
为了防止这种误解,许多组织要求不再使用#define TRUE !FALSE
或与TRUE
比较应更改为!FALSE
:
// Should not
if (var_bool == TRUE) {
...
}
//Should
if (var_bool != FALSE) {
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.