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