我想问一个关于下面代码的问题。
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
为什么代码打印“21 2 1”而不是“1 2 0”?
谢谢你的帮助。
我想问一个关于下面代码的问题。
int a=1, b=3, c=1;
if((a||c--)&&(c&&b--)) printf("%d",b);
printf("%d %d %d",a,b,c);
为什么代码打印“21 2 1”而不是“1 2 0”?
谢谢你的帮助。
由于 or 在 (a||c--) 中立即被评估为真,因此 c-- 永远不会被评估。编译器会这样做。如果一个陈述立即成立,它就不会费心评估其余部分。因此, c 永远不会递减,因为 or 的右侧永远不会被评估。
你可以想象这个 if 语句
if((a||c--)&&(c&&b--)) printf("%d",b);
以下方式
if ( a )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
else if ( c-- )
{
if ( c )
{
if ( b-- )
{
printf("%d",b);
}
}
}
所以如果第一个 if 语句中的表达式
if ( a )
评估为逻辑真然后这个 if 语句
else if ( c-- )
永远无法控制。
来自 C 标准(6.5.14 逻辑或运算符)
4 不同于按位 | 运算符,|| 运算符保证从左到右的评估;如果计算第二个操作数,则在第一个和第二个操作数的计算之间存在一个序列点。如果第一个操作数比较不等于 0,则不计算第二个操作数。
两者||
和&&
强制从左到右评估 - 首先评估 LHS并应用所有副作用,然后根据结果评估 RHS。
两个运算符短路:
a || b
,如果a
不为零,则表达式的结果与1
的值无关b
,因此b
不计算;a && b
,如果a
为零,则表达式的结果与0
的值无关b
,因此b
不计算。&&
优先级高于||
,因此a || b && c
被解析为a || (b && c)
。
将所有这些放在一起,(a||c--)&&(c&&b--)
评估如下:
a || c--
评估如下:
a
被评估 - 它的结果是1
,所以
c--
未评估;因为 thisc
的值没有改变,并且
1
c && b--
评估如下:
c
被评估 - 它的结果是1
,所以
b--
被评估 - 它的结果是3
; 作为副作用 b
减少,和
1
a || c--
并c && b--
评估为1
a
和的值c
不变(分别为1
和1
),而b
已递减,其值为 now 2
。