繁体   English   中英

#define TRUE !FALSE vs #define TRUE 1

[英]#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

要了解原因,请记住数组索引是可交换的(请参阅此问题我的回答,并且索引运算符[]绑定比!更紧密。

这里的教训是:

  1. 对于任何打算用作表达式的宏,整个宏定义都应该括在括号中——即使您想不出有什么重要的情况。

  2. 把事情简单化。 在 C 中, 0是唯一的假值, 1是规范的真值。 (任何非零值都是“真”,但内置的“布尔”运算符总是产生01 。)使用! 运算符将TRUE定义为FALSE (反之亦然)只是一种不必要的复杂化。

如果可以,请使用<stdbool.h> 如果你不能(因为你坚持使用 C99 之前的编译器),我建议这样做:

typedef enum { false, true } bool;

它与 C99 的_Bool / bool不太一样(转换到这种bool类型没有标准化为01 ),但它几乎可以满足所有用途。

差别不大。

#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。没问题。

他们只是一样。

  • !01所以!FALSE1

#define TRUE !FALSE根本没有技术优势,尽管它存在很长时间并且出现在很多地方。

#define TRUE !FALSE可能会被误解,人们可能认为TRUE代表每个不是0值。

  • 只有1等于TRUE ,其他值如23255 ...(其中!=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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM