ISO C和C99都这样定义!
。
逻辑非运算符!的结果是0,如果其操作数的值与0不相等,则为1。结果的类型为int。表达式!E等效于(0==E)。
因此,!0
的计算结果为1
。假设使用符合标准的C编译器,两个选项将具有相同的结果。此外,没有运行时惩罚,编译器将在编译时将!0
折叠为1
。
如果您想将其推向逻辑的极端,并且不做任何有关真或假的假设......
#define TRUE (1==1)
#define FALSE (!TRUE)
(1 == 1)
不产生值为1
的int
类型或者!(1 == 1)
不产生值为0
的int
类型,我仍然会感到惊讶。我相信,将TRUE
定义为1
,将FALSE
定义为0
一直是有效的,只要存在一种名为“C”的语言(可能追溯到B和BCPL)。 - Keith Thompson选项2没有任何好处,因为C标准保证! 0
的结果是1。
以那种方式定义TRUE
是旧源代码的主要特点,可能是为了遵循样式指南,尽可能避免使用"神奇常数"。
!
不是在使用 TRUE
时必须始终执行的附加操作吗?(假设编译器没有针对其进行优化)?如果不是,那么 !0 = 1
部分是在哪里处理的呢? - Markus Weninger!
、==
、<
等)对于 false 产生 0
,对于 true 产生 1
。 - Keith Thompson#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
TRUE[arr] == 0
[]
比!
具有更高的优先级。对于任何旨在用作表达式的宏,整个宏定义都应该用括号括起来 - 即使你想不到会产生影响的情况。
保持简单。在C中,0
是唯一的假值,1
是规范的真值。(任何非零值都为“真”,但内置的“布尔”运算符总是产生0
或1
。)使用!
运算符将TRUE
定义为FALSE
(反之亦然)只是一种不必要的复杂化。
<stdbool.h>
。如果不能(因为你被困在一个C99之前的编译器中),我建议这样做:typedef enum { false, true } bool;
这与C99的_Bool
/ bool
不完全相同(转换为此 bool
类型不会标准化为 0
或 1
),但对于几乎所有目的而言都足够接近。
!0
;我已经修复了它。 - Keith Thompson差别不大。
#define TRUE 1
相对于 #define TRUE !FALSE
稍微占有一点优势,因为 1
是一个单独的项目,不受运算符优先级的影响。
!FALSE
可以被写成 (!FALSE)
,以适应那些尝试使用 ++ -- [] . ->
的奇怪代码,这些运算符与 FALSE
有更高的优先级。
++TRUE
的用途,但我可以想象它会引发麻烦。 - Fantastic Mr Fox++TRUE
会出错,因为你不能对一个常量值应用++
运算符——但是我在我的答案中有另一个例子。 - Keith Thompson没有太大区别。但我认为#define TRUE 1
更好。
如果您使用#define TRUE !FALSE
:
FALSE
是0,而TRUE
是除了0以外的所有数字。
如果您使用#define TRUE 1
:
FALSE
是0,而TRUE
是1。没有问题。
在 C 语言中,TRUE 被正确定义为 (!FALSE),因为零 (0) 是 FALSE,而 FALSE 是零 (0),任何其他值都是 TRUE。你几乎可以使用任何变量作为布尔表达式,如果它非零,则表达式的值为 TRUE。一个空指针就是零,这正是它被定义为 NULL 的原因。字符串的结束标志字符 ('\0') 也是零。有很多代码利用了这个事实。请考虑以下示例:
while ( *d++ = *s++ );
复制将在复制完结束字符串字符时结束。这个习惯用语非常普遍。不必担心缓冲区大小问题。
这是为什么如果您没有现代的专用布尔类型,其中唯一可能的值为TRUE和FALSE,那么测试等于TRUE是一个坏主意的一个原因。我建议您养成无论如何都测试不等于FALSE的习惯,出于安全考虑。您可能并不总是能够使用新的、闪亮的工具。
它们只是相同的。
!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) {
...
}
!
的情况。而且你搞反了,因为它看起来确实像是在倡导双重否定。你应该使用 var_bool == TRUE
。var_bool == TRUE
比 var_bool != FALSE
更清晰。或者我应该说 var_bool == TRUE
不比 var_bool != FALSE
更不清晰?;) 而且 if( var_bool )
更加不不清晰。 - Schwernif( var_bool )
和 if( !var_bool )
更好。 - Schwernvar_bool != FALSE
是一个双重否定,增加了复杂性,应该避免使用(或者我应该说“不会增加简单性,不应该使用”)。一个体面的风格将推荐 if( var_bool )
来完全避免这个问题。任何能够编写工作的 C 代码的人都不会认为 #define TRUE !FALSE
可能会将 TRUE
设置为 255 或 2 或 3,而且这些都不重要,因为它不应该被用作数字。 - Schwernsome_function(FALSE)
意图将逻辑上的假值发送给some_function
,而不是整数0。比较真值测试不起作用,因为在C语言中,所有非零数字值和非NULL指针都是逻辑上的真值。比较FALSE失败,因为仅将FALSE改为TRUE即可破坏测试。那些规定这样做的风格指南是误导人的 - 在C语言中,应始终使用if (...)
和if (!...)
来测试真值。 - user4815162342if (x != FALSE)
和if (x == FALSE)
时优先于使用if (x)
和if (!x)
吗?我从未见过这样的指南。 - user4815162342
stdbool.h
?在标准宏存在的情况下使用自制宏是一个非常糟糕的想法。 - too honest for this site<stdbool.h>
头文件时,true
、false
和bool
才会被定义。 - Keith Thompson_Bool
/bool
特性被精心设计,以避免破坏使用标识符true
、false
和bool
的现有代码。我想未来的C标准可能会使它们都成为关键字(类似于C++),但我会感到惊讶。(非原型函数声明自1989年以来已经过时,28年后我们仍然卡在这里。) - Keith Thompson