!! c运算符,是两个非吗?

38

我在阅读这个代码,并遇到了这一行

 switch (!!up + !!left) {

什么是 !! 运算符?它表示两个逻辑非吗?


5
你有没有考虑过,你知道的,去尝试一下并找出答案呢? - Brian Roach
3
相反,双重否定技巧经常被使用。Linux内核源代码中就有一些使用它的例子,而且我非常确定内核黑客知道他们在做什么。 - C2H5OH
11
它是逻辑“是”的运算符。 - James McNellis
5
@weston的(up || left)将产生01,而(!!up + !!left)将产生012 - kittemon
显示剩余4条评论
4个回答

58

是的,它是两个感叹号。

!!aa 非零时为 1,当 a 等于 0 时为 0

你可以把 !! 看作是将值限定在 {0,1} 范围内。我个人认为这种用法是一种尝试显得高级的不好表现。


18
不要混淆与难以解开的双结。 - FlavorScape
6
更适合描述的不是“夹紧”,而是“规范化”。 - kittemon
9
如果您不喜欢它,您更喜欢什么?(_Bool)(如果已经包含了stdbool.h,则为(bool))适用于C99,但似乎过于依赖C99,并且理解如何将强制转换为布尔值的人要比理解!!惯用法的人少得多。另一个选择是expr?1:0,这只是丑陋而过于啰嗦的。 - R.. GitHub STOP HELPING ICE
一种试图显得花哨的糟糕尝试 - Rob

14
你可以这样想:
!(!(a))

如果您一步一步来做,这就有意义了。

result = !42;    //Result = 0
result = !(!42)  //Result = 1 because !0 = 1  

这将返回1与任何数字 (-42, 4.2f等),但只有在0的情况下才会发生这种情况

result = !0;    //Result = 1
result = !(!0)  //result = 0

8

!! 是一个更便携的(C99之前的)(_Bool) 的替代选择。


4

你说得对。是两个nots。为了理解为什么要这样做,请尝试以下代码:

#include <stdio.h>

int foo(const int a)
{
    return !!a;
}

int main()
{
    const int b = foo(7);
    printf(
        "The boolean value is %d, "
        "where 1 means true and 0 means false.\n",
        b
    );
    return 0;
}

它输出的结果是 布尔值为1,其中1表示真(true),0表示假(false)。如果去掉!!,它会输出布尔值为7,其中1表示真(true),0表示假(false)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接