我遇到了以下代码片段:
pt->aa[!!(ts->flags & MASK)] = -val;
!!
(双感叹号/双非运算符)在C语言中代表什么意思?(!!NULL) == NULL
是否成立?
我遇到了以下代码片段:
pt->aa[!!(ts->flags & MASK)] = -val;
!!
(双感叹号/双非运算符)在C语言中代表什么意思?(!!NULL) == NULL
是否成立?!
是否定运算符。所以!!
是双重否定(即肯定)。重要的是结果将是一个int
。
x == 0
,则!!x
就是!!0
,即!1
,即0
。x != 0
,则!!x
就是!!(!0)
,即!!1
,即!0
,即1
。!!
通常用于将任何非零值转换为1,同时确保0仍然保持为0。
实际上,!!NULL == NULL
,因为!!NULL == !!0
,而!!0 == !1
,最终!1 == 0
。
因此,在你引用的这段简短的代码中,如果括号中的表达式的值为NULL
,则数组下标将为0
,否则为1
。
int
类型的 0
或 1
。 - pmgNULL
是0
,那么(!!NULL) == NULL
为真。如果NULL
是(void*)0
这样的值,则可能会出现指针与整数比较的警告。使用!!
的主要目的是将“真值”和“假值”表达式结果转换为整数。 - Mike DeSimone!!false
是 0
,!!true
是 1
。 - Justin ᚅᚔᚈᚄᚒᚔ(void*)
警告, 在某些罕见的情况下,计算机中空指针的值可能为非零,因此C标准允许NULL为任何值,例如它可以是(void*)INT_MAX
,这会使您的语句变成错误的。我不确定百分之多少的C代码在这样的系统上运行失败,但没有必要鼓励人们做出非标准的假设并编写更多非标准代码。 - Theodore Murdock这种技巧通常被(滥)用于通过反复应用布尔非运算符!
将任何值转换为int
类型的0或1。
例如:!56
的值为0,因为当将56视为布尔值时它是“true”。这意味着!!56
的值为1,因为!0
为1。
pt->aa[(ts->flags & MASK) != 0]
,因为我认为这更清晰明确。 - unwind!E
与E == 0
相同,因此!!E
与(E == 0) == 0
相同。 !!
用于规范布尔值。
#include <stdbool.h>
pt->aa[(bool)(ts->flags & MASK)] = -val;
pt->aa[(ts->flags & MASK)!=0] = -val;
或者
pt->aa[(ts->flags & MASK)?1:0] = -val;
它将数字转换为规范的布尔值。
需要注意,在这种情况下这一步非常重要,因为结果将用于索引数组。
!!x
就是 !(!x)
。NULL
定义为 0,则 !!NULL == !!0 == !(!0) == !(1) == 0
。在某些情况下,例如在条件语句中进行赋值操作且有多个表达式时,使用!!是让编译器保持安静的不错方式。
int _blah = 100;
int *blah;
if ( _blah > 100 && !!(blah = &_blah) ) {
// do stuff
}
!!
来将int
转化为0
或1
位。 - Grijesh Chauhan