逻辑 AND OR 和递增优先级

Logical AND OR and increment precedence

我想问一个关于下面代码的问题。

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 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.

||&& 都强制从左到右评估 - 首先评估 LHS 并应用所有副作用,然后基于结果 RHS 被评估。

两个运营商短路:

  • for a || b,如果a非零,那么无论b的值如何,表达式的结果都是1,所以b 未评估;
  • 对于a && b,如果a为零,则无论b的值如何,表达式的结果都是0,所以b未评估。

&&的优先级高于||,所以a || b && c被解析为a || (b && c).

将所有这些放在一起,(a||c--)&&(c&&b--) 的计算结果如下:

  1. a || c-- 计算如下:
    1. a 被评估 - 它的结果是 1,所以
    2. c-- 评估;因此 c 的值没有改变,并且
    3. 表达式的结果是1
  2. c && b-- 计算如下:
    1. c 被评估 - 它的结果是 1,所以
    2. b-- 被评估 - 它的结果是 3;作为 副作用 b 递减,并且
    3. 表达式的结果是1
  3. a || c--c && b-- 的计算结果都是 1

ac的值不变(分别为11),而b已经递减,其值是现在 2.