Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C #定义为真!FALSE vs#定义TRUE 1_C - Fatal编程技术网

C #定义为真!FALSE vs#定义TRUE 1

C #定义为真!FALSE vs#定义TRUE 1,c,C,抛开c99已经存在这一事实不谈,在C中定义宏来处理布尔类型时,以下两者之间有什么区别吗 #define FALSE 0 #define TRUE 1 // Option 1 #define TRUE !FALSE // Option 2 ,这似乎没有什么区别。这两种方案都有技术优势吗?(不包括第二个例子在C++ +>代码中> Boo.对象更好的工作。) < P>对选项2没有好处,如!C标准保证0评估为1 以这种方式定义TRUE是旧资料的主要内容,大概是为了遵循风格指南,尽可能

抛开c99已经存在这一事实不谈,在
C
中定义宏来处理布尔类型时,以下两者之间有什么区别吗

#define FALSE 0

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

,这似乎没有什么区别。这两种方案都有技术优势吗?(不包括第二个例子在C++ +>代码中> Boo.<代码>对象更好的工作。)

< P>对选项2没有好处,如<代码>!C标准保证0评估为1


以这种方式定义
TRUE
是旧资料的主要内容,大概是为了遵循风格指南,尽可能避免使用“神奇常数”。ISO C和C99都定义
像这样

逻辑求反运算符的结果!如果 其操作数比较不等于0,如果其操作数的值 比较值等于0。结果的类型为int。表情!E是 相当于(0==E)

所以
!0
的计算结果为
1
。给定一个符合标准的C编译器,您的两个选项将得到相同的结果。此外,没有运行时惩罚,编译器将不断折叠
!编译时从0
1


如果你想把它带到逻辑的极端,不去假设什么是对的或错的

#define TRUE  (1==1)
#define FALSE (!TRUE)
这样做的好处是无论使用何种语言,都是正确的。例如,在shell中,0通常被视为“真”或“非错误”

从C没有一个统一的标准的时候起,这种事情就已经过时了。例如,第一版的第369页就提倡这一点。当它在1993年发布时,很有可能您的C编译器不符合ISO标准,并且stdbool.h不存在。“代码完整”也适用于使用多种不同语言的多语言程序员。有些,如shell和Lisp,对真理的定义不同。

差别不大

#define TRUE 1
#define TRUE稍有优势!FALSE
,因为
1
是不受运算符优先级影响的单个项

!FALSE
可以是
(!FALSE)
来处理试图使用
+-[].->,其优先级高于
FALSE

#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
选项2给出了:

TRUE[arr] == 0
要了解原因,请记住数组索引是可交换的(请参阅和),并且索引运算符
[]
绑定得更紧密

这里的教训是:

  • 对于任何打算用作表达式的宏,整个宏定义都应该用括号括起来——即使你想不出它在什么情况下会起作用

  • 保持简单。在C中,
    0
    是唯一的假值,
    1
    是标准的真值。(任何非零值都是“真”,但内置的“布尔”运算符总是产生
    0
    1
    ),使用
    运算符定义
    true
    (反之亦然)这只是一个不必要的复杂问题

  • 如果可以,请使用
    。如果不行(因为您使用的是C99之前的编译器),我建议您:

    typedef enum { false, true } bool;
    
    它与C99的
    \u Bool
    /
    Bool
    (转换为这种
    Bool
    类型并没有标准化为
    0
    1
    ),但几乎在所有方面都足够接近。

    它们完全相同

    • !0
      1
      所以
      !FALSE
      1
    #define TRUE!FALSE
    虽然存在了很长一段时间,而且在很多地方都出现了,但它并没有任何技术上的好处

    #定义真!假
    可能会被误解,人们可能会认为
    代表每一个不是
    0
    的值

    • 只有
      1
      等于
      TRUE
      ,其他值如
      2
      3
      255
      …(其中
      !=0
      )不等于
      TRUE
    为了防止这种误解,许多组织要求不再使用
    #定义真!假
    ,或者将与
    的比较改为
    !假

    // Should not     
    if (var_bool == TRUE) {
    ...
    }
    
    //Should    
    if (var_bool != FALSE) {
    ...
    }
    

    在C语言中,TRUE被正确地定义为(!FALSE),因为当0(0)为FALSE,FALSE为0(0)时,任何其他值都为TRUE。几乎可以将任何变量用作布尔表达式,如果它为非零值,则表达式的值为TRUE。空指针就是因为这个原因而为零。字符串结尾字符('\0')也是如此。编写了大量代码来利用这一事实。请考虑:

    while ( *d++ = *s++ ); 
    
    复制字符串结尾字符时,复制将结束。这种习惯用法非常常见。不要介意缓冲区大小问题

    这就是为什么如果你没有一个现代专用的布尔类型,其中唯一可能的值是TRUE和FALSE,那么测试是否等于TRUE是一个坏主意的原因。为了安全起见,我建议你养成一种习惯,不管怎样,测试是否等于FALSE。你可能并不总是能够使用new和shin