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?
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?
在这种情况下,它也被解析为&&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
将标签用作值是一种gcc扩展(参见此处)。你的表达段:
c = i &&&& i;
等于: c = i && (&&i); &&i标签的地址在哪里i。
请记住,您在i这里组合了两个完全不同的“对象”。第一个是i循环的变量0, 1, 2,而第二个是标签i,其地址总是一些非零值。
这意味着0仅当变量 i为时,放置在 C 中的结果才会为 (false) 0。这就是你得到0, 1, 1序列的原因。
顺便说一句,如果我的一个手下给我买了这样的代码用于生产用途,我会认真考虑“员工管理实践”。在我看来,任何消除这种怪物可能性的东西都是一件好事:-)