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