在C语言中,“&&”操作符是什么?

198
#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
43
while (i &&& i <-- j) {} 可以翻译为“当i不为0且i减小到等于j时执行循环体”。注意,&&& 是一个自定义的逻辑运算符,表示逻辑与运算中的短路效应。 - kennytm
5
可能是重复的问题:在C编程中可以使用三个减号吗?它代表什么意思? - Anirudh Ramanathan
8
不是重复的问题,但是有一个类似的问题,这是一个好的链接。 - Nathan Cooper
1
这是同样的经典最大匹配规则,正如@Cthulhu已经提到的那样。请注意,这个问题又是一个重复的问题,我已经发现过一次了,但没有被标记为重复。 - aiao
显示剩余10条评论
2个回答

275

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

对于用户定义的类型,您可以实际上重载一元运算符&,但这仍然是一个非常糟糕的想法

如果您打开警告,您将得到以下内容:

警告:‘i’的地址将始终评估为‘true’


1
为什么不这样写:c = i & (&&i);?其中 i 是某个标签。 - anishsane
4
“i”被定义为“int”,问题中没有标签。另外,“maximal munch”… - Luchian Grigore
5
@anishsane:而且使用&&运算符获取标签地址是非标准的gcc扩展。但即使它是标准的,最大匹配规则也会阻止它被解析成那种方式(除非你插入一个空格)。 - Keith Thompson
实际上,&i 可以评估为 false。它有时用于默认值。例如:void fn(type& x = *reinterpret_cast<type*>(NULL)); 如果在不带参数的情况下调用 fn,则 &x 的值是多少?它是 0,也就是 false。然而,如果按照所描述的方式使用它,除非 i == 0,否则它总是为 true,如果一个人像我描述的那样使用它,它将是 c = &i && i - Adrian
@EmilioGaravaglia 任何关于代码片段行为的陈述都应该假定已经隐含了“(除非已经存在未定义行为,否则任何事情都可能发生)”。 - M.M
显示剩余6条评论

120

C语言中没有 &&& 运算符或标记。但是存在 && (逻辑 "and") 和 & (一元取地址运算符或按位 "and") 运算符。

根据最长匹配规则,这个:

c = i &&& i;

等同于这个:

c = i && & i;

如果 i&i 都为真(即非零值),则它将 c 设置为 1,否则如果其中一个为假,则将其设置为 0。

对于 int 类型的变量,任何非零值都会被视为 true。对于指针类型的变量,任何非空值都会被视为 true (并且对象的地址始终非空)。因此:

如果 i 是非零值,则将 c 设置为 1,如果 i 等于零,则将其设置为 0

这意味着在这里使用 &&& 只是出于故意混淆。分配也可以是以下任何一种:

c = i && 1;
c = !!i;
c = (bool)i;          // C++ or C with <stdbool.h>
c = i ? 1 : 0;        /* C */
c = i ? true : false; // C++

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