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

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

0
1
1

在上述程序中如何评估 c?

4

2 回答 2

28

在这种情况下,它也被解析为&&and &&。第一个是logical AND但第二个&&是标签i的地址而不是变量的地址i。(这是 gcc 扩展)

这将被解析为 c = (i) && (&&i); // 括号只是为了使其易于阅读。

&给你变量的地址i您在几分钟前刚刚问过这个问题。

有关标签和值的地址的更多信息,请参见这个 gcc 扩展。

编辑:因为&&逻辑与总是遵循语句的短路。因此在第一种情况下,它会0因为它找到i=0所以它不会去&&i(逻辑表达式的第二部分)。

但在所有后续情况下,它i不会0给出TRUE并将转到下一个表达式&&i,即标签地址i(并且地址i将始终评估为TRUE。)

因此,完整表达式的结果将始终是TRUE均值1,除了第一种情况 where iis 0。因此,您看到了结果

0
1
1
于 2012-12-19T07:12:58.167 回答
25

将标签用作值是一种gcc扩展(参见此处)。你的表达段:

c = i &&&& i;

等于: c = i && (&&i); &&i标签的地址在哪里i

请记住,您在i这里组合了两个完全不同的“对象”。第一个是i循环的变量0, 1, 2,而第二个是标签i,其地址总是一些非零值。

这意味着0仅当变量 i为时,放置在 C 中的结果才会为 (false) 0。这就是你得到0, 1, 1序列的原因。

顺便说一句,如果我的一个手下给我买了这样的代码用于生产用途,我会认真考虑“员工管理实践”。在我看来,任何消除这种怪物可能性的东西都是一件好事:-)

于 2012-12-19T07:18:25.933 回答