Pet*_*man 9 c embedded microchip mplab
问题:
是否做了if(SomeFunction() == TRUE)而不是做if(SomeFunction())某些类型的编码错误?我试图了解这是否可以防止某些隐藏的地雷,或者是否是某人编写代码并且不太明白如何评估表达式的结果.我明白,如果做得对,这两件事情的评价都是一样的.就像if(value == 42)并if(42 == value)评估相同 - 仍然,有些人更喜欢第二个版本,因为如果有人输错了==并且写入=而产生编译器错误.
背景: 我继承了一些4年或5年前由不在这里工作的人写的嵌入式软件.我正在进行一些重构以摆脱数百行函数和全局变量以及所有爵士乐,所以这个东西是可读的,我们可以继续保持它.代码是c用于pic微处理器.这可能相关也可能不相关.该代码有各种在它的尖叫奇怪的东西"不知道他们在做什么",但在这里我想了解是不是有一个很好的理由一个特定的模式(反模式?)
模式: 这里有很多if语句采用的形式
if(SomeFunction() == TRUE){
. . .
}
Run Code Online (Sandbox Code Playgroud)
其中SomeFunction()定义为
BOOLEAN SomeFunction(void){
. . .
if(value == 3)
return(FALSE);
else
return(TRUE);
}
Run Code Online (Sandbox Code Playgroud)
让我们忽略SomeFunction从if语句的主体返回TRUE或FALSE的奇怪方式,以及他们使'return'看起来像函数调用的奇怪方式.
这似乎打破了c认为'true'和'false'的正常值.就像,他们真的想确保返回的值等于任何被定义为TRUE的值.这几乎就像他们正在制作三种状态 - TRUE,FALSE和'其他'而且他们不希望在返回"其他东西"的情况下采用'if'语句.
我的直觉是,这是一种奇怪的反模式,但我想给这些家伙带来怀疑的好处.例如,我认识到if(31 == variable)看起来有点奇怪,但它是这样编写的,所以如果你输错了==你不会意外地将31分配给变量.如果这些人写了这个保护措施来防范类似的问题,或者这只是胡说八道.
附加信息
typedef enum _BOOLEAN { FALSE = 0, TRUE } BOOLEAN;Kei*_*son 17
有没有充分的理由去做
if(SomeFunction() == true)而不是做if(SomeFunction())
没有.
如果SomeFunction()返回类型的结果_Bool,那么相等性比较应该是可靠的(假设结果的评估不涉及未定义的行为).但是使用TRUE而不是true和类型名称BOOLEAN而不是_Bool或bool表示结果不是实际的_Bool(仅在C99或更高版本中可用),而是一些特殊的布尔类型 - 也许是别名int.
任何标量类型的值都可以用作if语句中的条件.如果该值等于零,则条件为假; 否则,条件为真.如果TRUE被定义为1,并且SomeFunction()返回3,那么测试将失败.
写作
if (SomeFunction()) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
更简单,更清晰,更有可能正常行事.
请注意,例如,声明的isdigit()等函数<ctype.h>不仅仅返回0或1; 如果参数是一个数字,isdigit()可以(并且确实)返回任何非零值.使用它的代码应该正确处理它 - 通过不比较它的相等1,to true或to TRUE.
话虽如此,可能有一个合理的理由来比较某些东西的相等性TRUE- 如果重要的是结果是否等于TRUE或具有其他非零值.但在这种情况下,使用名称BOOLEAN并TRUE具有误导性.布尔类型的重点是值为true或false; 没有"可能",如果碰巧有不同的真理表示,你不应该关心你拥有哪一个.
我尝试遵循的准则是:
决不相等或不等的比较逻辑布尔值true或者false(或0,1,FALSE,TRUE).!如果要反转测试,只需使用操作员直接测试该值.("逻辑布尔"值既可以是类型_Bool,也可以用来区分真假,而无需额外的信息.如果_Bool不可用,则后者可能是必要的.)比较false可以是安全的,但没有理由这样做; 直接比较值仍然更清晰.
如果有人告诉你的话
if (SomeFunction() == true)
Run Code Online (Sandbox Code Playgroud)
比...更好
if (SomeFunction())
Run Code Online (Sandbox Code Playgroud)
只要问他们为什么
if ((SomeFunction() == true) == true)
Run Code Online (Sandbox Code Playgroud)
甚至不是更好.
另请参见comp.lang.c FAQ的第9节.它对C99前解决方案的重视可能有点过时,但它仍然有效.
更新:问题询问一个返回TRUE类型值的函数BOOLEAN,定义如下:
typedef enum { FALSE, TRUE } BOOLEAN;
Run Code Online (Sandbox Code Playgroud)
这样的定义是在1999年之前-C是有用的,但加入C99预定义的布尔类型_Bool和首标<stdbool.h>,它定义宏bool,false和true.我目前的建议:使用<stdbool.h>除非严重担心您的代码可能需要与不支持它的实现一起使用.如果这是一个问题,你可以使用
typedef enum { false, true } bool;
Run Code Online (Sandbox Code Playgroud)
要么
typedef int bool;
#define false 0
#define true 1
Run Code Online (Sandbox Code Playgroud)
(我更喜欢第一个.)这与C99定义不是100%兼容,但如果您明智地使用它,它将正常工作.