NOT false 和 true 的区别

5

I have this chunk of code:

if ( ( data.is_err != FALSE ) && ( available != FALSE ) )
    {
        Set_Dtc_TimerChange(DTC_VPOS, +dt_ms);
    }

为什么要使用“不等于false”而不是直接使用“等于true”?有区别吗?

下面已经有几个正确的答案了。我想补充一点,当我看到用于这些基本值的宏时,我不信任它们,因为我曾经在过去看到过令人惊讶的宏值(并浪费了太多时间)。因此,每次看到它们时,我总是会查一遍以确保安全。 - donjuedo
如果它们来自某些垃圾非标准编译器,但使用 0 代表 FALSE,那么你根本不应该这样比较。布尔(或真/假 int)变量的正确且更易理解的方式是编写 if ( data.is_err && available ) ...。大声朗读,这直接说明了你想要什么,而不必三思而后行。 - too honest for this site
3个回答

12

这是一个关于C语言的问题,而不是EE(电子工程),但由于C语言与硬件非常接近...

旧版C语言中false的定义为0,而所有其他值都是true,也就是说

if( 0 ){ ... }

不会执行这段代码,举个例子

if( 1 ){ ... }
if( -1 ){ ... }
if( 42 ){ ... }

所有都将。因此,您可以测试一个真值是否等于FALSE(定义为0),但是当您想将其与true进行比较时,您会使用哪个值作为true呢?有人说TRUE必须被定义为(!FALSE),但这将产生-1,这是一个真值,但不是唯一的真值。

因此,程序员往往避免与TRUE进行比较。

现代C语言应该通过将TRUE定义为(我认为)1来解决这个问题,但仍有有趣的后果,比如

int probably( void ){ return 42; }
if( probably() ){ ... }
if( probably() == TRUE ){ ... }

这里的问题可能出在 probbaly() 函数上,它返回了一个含糊不清的真值。

个人而言,我会这样写:

if ( data.is_err && available ) { ... }

我认为这样更易读,并且避免了比较。

(顺便问一下,当数据出错时,某物怎么可能可用?)


1
回复:“当你想将其与true进行比较时,你会使用哪个值作为true?”实际上你不必将任何东西与true进行比较。你可以只是使用条件本身(或其否定)作为if子句的谓词(就像你在最后一个例子中所做的那样)。 - The Photon
1
@The Photon:因为这会破坏旧代码,对于已经有大量安装的代码库来说,这是绝对不可取的。 - Wouter van Ooijen
3
我很惊讶一款 C 编译器会认为 42 != TRUE,因为这是“生命、宇宙和万物的答案”... - Ricardo
2
必须定义为(!FALSE),但这会产生-1。不,那是~FALSE!FALSE是(正)1 - Ben Voigt
2
@hobbs:我们在谈论C语言,对吧?一个!0表示除了1以外的任何值都不是C语言。 - Ben Voigt
显示剩余11条评论

8

这段代码可以安全地被替换为:

if (  data.is_err &&  available ) { 
    Set_Dtc_TimerChange(DTC_VPOS, +dt_ms); 
}

除非在程序的某处FALSE有一些非传统的定义。一个好的编译器将为任何形式产生等效的代码,但更易读的形式更受欢迎。


1

C语言没有布尔类型。相反,它将0视为假,任何其他值都视为真。因此,没有值可以用来测试一个值是否表示为真。如果您编写惯用的C代码,则这并不重要:if (x) ...总是会做正确的事情。那些不习惯这种习惯用法的人喜欢明确地对某些假表示进行测试,但从未解释为什么他们将其限制在一个级别上。毕竟,x != FALSE只是一个值,按照同样的论点需要进行测试:if ((x != FALSE) != FALSE)...


2
C99引入了_Bool类型。 - Eugene Sh.
@EugeneSh。- 感谢您提供的信息。我的C语言知识还没有更新到与C99相匹配的水平。 - Pete Becker
@EugeneSh。虽然这是真实且非常有用的,但在嵌入式系统中,我们有时会被一些不太兼容的工具链所困扰,或者由于“遗留”代码而被困在C89中。如果可以,请务必使用C99和真正的布尔值,但不幸的是,有时仍然会出现这种情况。 - shenles
C 从一开始就有布尔表达式。它们只是用 01int 值来表示。这就是为什么旧代码通常会 #define FALSE 0 #define TRUE !FALSE 的原因。 - too honest for this site
@Olaf - 使用TRUE的定义并不具有在if语句中使用表达式的相同语义。对于许多x的值,if(x) whatever();将调用函数,但是if(x==TRUE) whatever();则不会。使用这些宏的代码不符合惯例且存在危险。 - Pete Becker
@PeteBecker:通常来说,与 true/false 进行比较是错误的做法,而且不够清晰。你永远不应该这样做,而是使用你评论中的第一种变体。顺便说一下:如果 xbool,那么比较是相同的。 - too honest for this site

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接