我的书中有一个问题:
#include<stdio.h>
void main()
{
int a=5, b=-7, c=0, d;
d = ++a && ++b || ++c;
printf("\n%d%d%d%d",a,b,c,d);
}
这个问题问我代码的输出是什么。我跑了,屏幕上的结果是6-601。我理解为什么a=6
和b=-6
,但我不明白为什么c=0
和d=1
?
答案 0 :(得分:15)
我相信你已经得到了答案,但是为了逐步详细说明,让我在这里再补充一点。首先,引用&&
和||
运算符的属性,分别来自C11
标准,章节§6.5.13和§6.5.13,
(I)
如果
&&
运算符的两个操作数都不等于0,则它将产生1;否则,它 收益率为0. [...]如果第一个操作数比较等于0 ,则为第二个操作数 操作数未被评估。
和
(II)
||
运算符如果其任一操作数比较不等于0,则应得1;否则,它 收益率为0. [...]。如果第一个操作数比较不等于0 ,则第二个操作数为 没有评估。
他们都保证从左到右的评估。所以,比较你的代码,
d = ++a && ++b || ++c;
就像
一样d = ((++a && ++b) || ++c );
评估为
d = (( 6 && ++b ) || ++c);
然后
d = ( ( 6 && (-6) ) || ++c);
现在处于上述阶段,(I)已经实现,并且归结为
d = ( 1 || ++c);
现在,在已经满足(II)的重点之后,不再对||
的RHS操作数进行进一步评估(即,++c
未被评估),并且它似乎为d = 1
,最终结果1存储在d
。
就是这样,a == 6
,b == -6
,c == 0
和d ==1
。
话虽如此,void main()
应更改为int main(void)
,至少要符合标准。
答案 1 :(得分:14)
||
OR运算符是短路的,这意味着如果左侧为真,则不评估右侧。在这种情况下,++a && ++b
的计算结果为true,因此永远不会运行++c
并且c
保持其值为零。
此外,由于评估为true,因此1
表示d
。
任何非零值都被视为true,布尔运算的结果被定义为0
或1
为整数。