C是什么“!!”?
我遇到以下代码片段:
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
。
因此,在引用的短代码中,如果括号中的expression式值为NULL
,则数组下标将为0
,否则为1
。
通常用(ab)通过重复应用boolean not操作符来将任何值转换成int
s 0或1 !
。
例如: !56
是0,因为在查看布尔值时,56是“真”。 这意味着!!56
是1,因为!0
是1。
!E
与E == 0
相同所以!!E
与(E == 0) == 0
。 !!
用于规范布尔值。
在C99中,您可以将其replace
#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,那么!!NULL == !!0 == !(!0) == !(1) == 0
。
! 是一个体面的方式来安静的编译器在某些情况下,如在一个以上的expression式条件赋值,例如:
int _blah = 100; int *blah; if ( _blah > 100 && !!(blah = &_blah) ) { // do stuff }
我不build议这样做 – 警告通常是为了执行良好的编码习惯。