C是什么“!!”?

我遇到以下代码片段:

pt->aa[!!(ts->flags & MASK)] = -val; 
  1. 什么!! (双感叹号/感叹号/两个不是操作符)代表c?
  2. 不是(!!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。

!EE == 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; 

生成的代码肯定是一样的。

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

请注意,在这种情况下,这样做是非常重要的,因为结果正在被用来索引一个数组。

  1. !!x只是!(!x)
  2. 如果NULL被定义为0,那么!!NULL == !!0 == !(!0) == !(1) == 0

! 是一个体面的方式来安静的编译器在某些情况下,如在一个以上的expression式条件赋值,例如:

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

我不build议这样做 – 警告通常是为了执行良好的编码习惯。