48

我遇到了以下代码段:

pt->aa[!!(ts->flags & MASK)] = -val;
  1. !!(双感叹号/感叹号/两个非运算符)在c中代表什么?
  2. 不是(!!NULL) == NULL吗?
4

7 回答 7

78

!是否定的。!!否定之否定也是如此。重要的是结果将是一个int.

  • !!x如果x == 0!!0,就是!1,就是0
  • !!x如果x != 0!!(!0),就是!!1,就是!0,就是1

!!如果您想将任何非零值转换为 1,同时确定 0 仍然是 0,则通常使用此方法。

事实上, ,!!NULL == NULL, 自!!NULL == !!0!!0 == !1终于!1 == 0

因此,在您引用的一小段代码中,0如果括号中的表达式的值为 ,则数组下标将为NULL1否则为。

于 2013-02-07T13:14:16.900 回答
28

它通常(ab)用于int通过重复应用布尔非运算符将任何值转换为 0 或 1 !

例如:!56是 0,因为 56 在被视为布尔值时是“真”。这意味着!!56是 1,因为!0是 1。

于 2013-02-07T13:15:21.900 回答
7

!E与 相同与E == 0相同。用于标准化布尔值。!!E(E == 0) == 0!!

于 2013-02-07T13:15:34.937 回答
4

在 C99 中,您可以将其替换为

#include <stdbool.h>


pt->aa[(bool)(ts->flags & MASK)] = -val;

当然,如果您的代码要移植到 C89,那么您最好执行 !! 诡计或

pt->aa[(ts->flags & MASK)!=0] = -val;

或者

pt->aa[(ts->flags & MASK)?1:0] = -val;

生成的代码肯定是相同的。

于 2013-02-07T14:28:05.400 回答
3

它将数字转换为规范的布尔值。

请注意,在这种情况下,这样做很重要,因为结果被用于索引数组。

于 2013-02-07T13:15:13.713 回答
2
  1. !!x只是一个!(!x)
  2. ifNULL定义为 0 then !!NULL == !!0 == !(!0) == !(1) == 0
于 2013-02-07T13:15:40.313 回答
1

!!是在某些情况下使编译器安静的一种不错的方法,例如在具有多个表达式的条件中赋值,例如:

int _blah = 100;
int *blah;
if ( _blah > 100 && !!(blah = &_blah) ) {
// do stuff
}

我不建议这样做——警告通常是为了强制执行良好的编码实践。

于 2013-02-07T21:42:45.557 回答