C中的&&&操作


195
#include <stdio.h>

volatile int i;

int main()
{
    int c;

    for (i = 0; i < 3; i++) 
    {
         c = i &&& i;
         printf("%d\n", c);
    }

    return 0;
}

使用编译的上述程序的输出gcc

0
1
1

使用-Wall-Waddress选项,gcc发出警告:

warning: the address of i will always evaluate as true [-Waddress]

c在以上程序中如何进行评估?


42
我相信是i && (&i)吗?有趣的是,我找不到关于SO的重复帖子。
irrelephant 2012年

42
while (i &&& i <-- j) {}
kennytm


8
不是重复的,而是一个类似的问题,这是一个很好的链接
Nathan Cooper

Answers:


272

这是c = i && (&i);,与第二部分是多余的,因为&i永远不会计算为false

对于用户定义的类型,您实际上可以在其中重载一元operator &,这可能有所不同,但这仍然是一个非常糟糕的主意

如果打开警告,您将得到类似以下内容的信息:

警告:“ i”的地址将始终评估为“ true”


1
为什么不:c = i & (&&i);; i标签在哪里?
anishsane 2012年

4
@anishsane i的定义为int,问题中没有标签。还有,最大的
mu

5
@anishsane:&&拿标签地址的操作员无论如何都是非标准的gcc扩展名。但是,即使它是标准的,最大的munch规则也将阻止它以这种方式进行解析(除非您插入空格)。
基思·汤普森

实际上,&i可以评估为false。它有时用于默认值。示例:如果不带参数调用in void fn(type& x = *reinterpret_cast<type*>(NULL)); 的值是什么?这是0,也就是假。但是,按照描述的方式使用它,除非且如我所描述的那样使用它,否则它将始终是true 。&xfnfni == 0c = &i && i
阿德里安

@LuchianGrigore:怎么回事?
阿德里安

118

&&&C中没有运算符或令牌。但是确实存在&&(逻辑“与”)和(逻辑&地址的“一”或按位“与”)。

根据最大的蒙克规则,这是:

c = i &&& i;

等效于此:

c = i && & i;

它设置c为1,如果这两个i&i是真实的,为0;如果其中一方是假的。

对于int,任何非零值都为true。对于指针,任何非null值都为true(并且对象的地址始终为非null)。所以:

它设置c如果为1 i是非零,或者0如果i等于零。

这意味着&&&此处仅用于故意混淆。分配可能是以下任何一项:

c = i && 1;
c = !!i;
c = (bool)i;          // C++ or C with <stdbool.h>
c = i ? 1 : 0;        /* C */
c = i ? true : false; // C++
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.