#define TRUE!FALSE vs #define TRUE 1

时间:2016-02-22 23:08:49

标签: c

除了c99之外stdbool.h已经存在这一事实,在定义宏以处理C中的布尔类型时,以下是否存在差异?

#define FALSE 0

#define TRUE 1       // Option 1 
#define TRUE !FALSE  // Option 2

From the live example here,它似乎没有什么区别。两种选择都有技术优势吗? (不包括第二个例子对c ++ bool个对象更好的事实。)

7 个答案:

答案 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 questionmy answer,并且索引运算符[]的绑定比!更紧密。

这里的课程是:

  1. 对于任何打算用作表达式的宏,整个宏定义应该括在括号中 - 即使你不能想到它会重要的情况。

  2. 保持简单。在C中,0是唯一的错误值,1是规范的真值。 (任何非零值都是“true”,但内置的“布尔”运算符总是产生01。)使用!运算符定义TRUEFALSE而言(反之亦然)只是一种不必要的复杂情况。

  3. 如果可以,请使用<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)

他们是一样的。

  • !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) {
...
}