逻辑 AND OR 和递增优先级

问题描述

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

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 逻辑 OR 运算符)

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--) 的计算方式如下:

  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 已递减,其值现在为 { {1}}。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...