在 int 或 uint 类型的数据上执行此操作!操作会发生什么情况

Do it on an int or uint type of data! What happens to the operation

提问人:xiaopengyou 提问时间:11/17/2023 更新时间:11/17/2023 访问量:64

问:

我在使用 ESP32-IDF 自动生成的代码时遇到了问题,其中以下代码用于在闪光灯的示例代码中默认翻转引脚电平

static uint8_t led_state = 0;

...

led_state = !led_state;  toggle the pin state

如何理解这里的“!”操作

我写了一个这样的小程序

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    uint8_t i = 2;
    printf("i = %d\n", i);
    i = !i;
    printf("i toggled\n");
    printf("i = %d\n", i);
    i = !i;
    printf("i toggled\n");
    printf("i = %d\n", i);
    return 0;
}

输出为

i = 2
i toggled
i = 0
i toggled
i = 1
C GCC 嵌入式 ESP32 ESP-IDF

评论

1赞 Eugene Sh. 11/17/2023
!是逻辑上的否定。它会将值转换为 ,而不是 。周期性地否定同一变量将使其在 和 之间交替。010001
1赞 Lundin 11/17/2023
“如何理解这里的'!'操作” 在该示例中,仅将其视为布尔值。这是草率的代码,这往往是这些Arduino:ish平台的标准。uint8_t

答:

4赞 ikegami 11/17/2023 #1

!是逻辑 NOT 运算符。

  • 如果它的操作数不等于零(即,如果它是真值),则返回(假值)。0
  • 如果它的操作数等于零(即,如果它是一个假值),则返回(一个真值)。1

C 逻辑运算符


如果需要设置特定位,可以使用移位。

led_state = !led_state;            // Toggle the state.
uint8_t bitmask = led_state << 1;  // 1 or 0 => 2 or 0.

如果要切换特定位,可以使用独占 or。

bitmask ^= 1 << 2;                 // Toggle the second bit directly.

评论

0赞 Lundin 11/17/2023
值得注意的是,where is 在 32 位 MCU 上肯定是错误的代码,例如这里提到的代码。 必须是 类型 。led_state << nled_stateuint8_tled_stateuint32_t