我遇到了以下代码段:
pt->aa[!!(ts->flags & MASK)] = -val;
!!
(双感叹号/感叹号/两个非运算符)在c中代表什么?- 不是
(!!NULL) == NULL
吗?
我遇到了以下代码段:
pt->aa[!!(ts->flags & MASK)] = -val;
!!
(双感叹号/感叹号/两个非运算符)在c中代表什么?(!!NULL) == NULL
吗?!
是否定的。!!
否定之否定也是如此。重要的是结果将是一个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
如果括号中的表达式的值为 ,则数组下标将为NULL
,1
否则为。
它通常(ab)用于int
通过重复应用布尔非运算符将任何值转换为 0 或 1 !
。
例如:!56
是 0,因为 56 在被视为布尔值时是“真”。这意味着!!56
是 1,因为!0
是 1。
!E
与 相同与E == 0
相同。用于标准化布尔值。!!E
(E == 0) == 0
!!
在 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;
生成的代码肯定是相同的。
它将数字转换为规范的布尔值。
请注意,在这种情况下,这样做很重要,因为结果被用于索引数组。
!!x
只是一个!(!x)
。NULL
定义为 0 then !!NULL == !!0 == !(!0) == !(1) == 0
。!!是在某些情况下使编译器安静的一种不错的方法,例如在具有多个表达式的条件中赋值,例如:
int _blah = 100;
int *blah;
if ( _blah > 100 && !!(blah = &_blah) ) {
// do stuff
}
我不建议这样做——警告通常是为了强制执行良好的编码实践。