【问题标题】:Logical AND OR and increment precedence [duplicate]逻辑与或和递增优先级[重复]
【发布时间】:2021-05-08 04:23:24
【问题描述】:

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

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”?

感谢您的帮助。

【问题讨论】:

  • 哪一部分让您感到困惑,开头的附加数字还是 0?请解释您期望的结果背后的原因。
  • 或使用衬衫电路评估
  • @MrTux 也许是裤子电路?

标签: c if-statement logical-or


【解决方案1】:

由于在 (a||c--) 中 or 被立即评估为真,因此 c-- 永远不会被评估。编译器会这样做。如果一个陈述立即成立,它就不会费心评估其余部分。因此,c 永远不会因为 or 的右侧而递减。

【讨论】:

    【解决方案2】:

    你可以想象这个 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,则第二个 不计算操作数

    【讨论】:

      【解决方案3】:

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

      两个运算符短路:

      • 对于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

      【讨论】:

        猜你喜欢
        • 2015-09-20
        • 2023-03-31
        • 1970-01-01
        • 2015-04-17
        • 2017-06-20
        • 2019-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多