首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用if (!! (expr) )而不是if (Expr)

使用if (!! (expr) )而不是if (Expr)
EN

Stack Overflow用户
提问于 2016-02-20 20:08:04
回答 3查看 3.9K关注 0票数 65

在阅读德州仪器为其SensorTag提供的示例代码时,我遇到了以下代码片段。

代码语言:javascript
复制
void SensorTagIO_processCharChangeEvt(uint8_t paramID) { 
    ...

    if (!!(ioValue & IO_DATA_LED1)) {
        PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
    } else {
        PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
    }

    if (!!(ioValue & IO_DATA_LED2)) {
        PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
    } else {
        PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
    }

    if (!!((ioValue & IO_DATA_BUZZER))) {
        Clock_start(buzzClockHandle);
    }
    ...
}

声明如下所示(在同一个文件中)。

代码语言:javascript
复制
#define IO_DATA_LED1   0x01
static uint8_t ioValue;

if (ioValue & IO_DATA_LED1)相比,if (!!(ioValue & IO_DATA_LED1))有什么优势吗

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-20 20:09:50

两次应用逻辑not (!)运算符的目的是将一个值规范化为0或1。在if语句的控制表达式中,这没有任何区别。if-语句只关心值是零还是非零,小的!!是完全没有用的。

一些编码风格指南可能会强制使用这种舞蹈,这可能是您发布的TI代码执行此操作的原因。不过,我还没有看到任何这样做的人。

票数 80
EN

Stack Overflow用户

发布于 2016-02-21 01:20:07

在MSVC中,在if语句中将整数隐式转换为bool可能会生成警告。通过!!这样做是不会的。类似的警告可能存在于其他编译器中。

因此,假设代码是在启用该警告的情况下编译的,并且决定将所有警告视为错误,那么使用!!是一种简短且可移植的方式,可以说“是的,我希望这个整数是一个bool”。

票数 16
EN

Stack Overflow用户

发布于 2016-02-25 07:44:16

虽然使逐位&的编译器警告静默是最有可能的,但这看起来也可能是重构的结果,以便从以下位置添加枚举以提高可读性:

代码语言:javascript
复制
PIN_setOutputValue(int,int,bool); //function definition
PIN_setOutputValue(hGpioPin, Board_LED1,!!(ioValue & IO_DATA_LED1));
PIN_setOutputValue(hGpioPin, Board_LED2,!!(ioValue & IO_DATA_LED2));
//note: the !! is necessary here in case sizeof ioValue > sizeof bool
//otherwise it may only catch the 1st 8 LED statuses as @M.M points out

至:

代码语言:javascript
复制
enum led_enum {
  Board_LED_OFF = false,
  Board_LED_ON = true
};
PIN_setOutputValue(int,int,bool); //function definition
//...
PIN_setOutputValue(hGpioPin, Board_LED1,!!(ioValue & IO_DATA_LED1)?Board_LED_ON:Board_LED_OFF);
PIN_setOutputValue(hGpioPin, Board_LED2,!!(ioValue & IO_DATA_LED2)?Board_LED_ON:Board_LED_OFF);

因为它超过了80个字符的限制,所以它被重构为

代码语言:javascript
复制
if (!!(ioValue & IO_DATA_LED1)) {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
}

if (!!(ioValue & IO_DATA_LED2)) {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
}

就我个人而言,为了可读性,我更喜欢初始版本,但当使用代码行作为度量标准时,这个版本很常见(我很惊讶它没有为每个状态声明变量,分别设置每个状态,然后使用它)。

这个“最佳实践”代码的下一个版本可能如下所示:

代码语言:javascript
复制
bool boardled1State;
bool boardled2State;
//...

boardled1State = !!(ioValue & IO_DATA_LED1);
boardled2State = !!(ioValue & IO_DATA_LED2);
//...

if (boardled1State) {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
}

if (boardled2State) {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
}
//... and so on

所有这些都可以像这样完成:

代码语言:javascript
复制
for (int i=0;i<numleds;i++)
        PIN_setOutputValue(hGpioPin, i ,!!(ioValue & (1<<i)));
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35523023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档