【问题标题】:++ has higher precedence than logical operator?++ 的优先级高于逻辑运算符?
【发布时间】:2013-01-18 16:48:21
【问题描述】:

如果是这样,下面程序的输出会是什么。

#include<stdio.h>
int main()
{
   int i=-3, j=2, k=0, m;
   m = ++i || ++j && ++k;
   printf("%d, %d, %d, %d\n", i, j, k, m);
   return 0;
}

在 gcc 下输出是 ** -2 2 0 1 ** 但如何?

【问题讨论】:

  • “man operator”,google会帮你找的
  • 这并不重要,不是吗?你永远不会在真正的程序中编写这样的代码。
  • 没错,但我对评估顺序很困惑,这就是我问的原因

标签: c operator-keyword


【解决方案1】:

++i 的值-2 不为零,因此在布尔上下文中为“真”,短路条件停在那里,j 和k 保留其原始值。布尔值“true”转换为整数值1,赋值给m。

【讨论】:

  • 但预增量的优先级高于 ||为什么 ++j 和 ++k 之前没有评估 ||
  • Precendence 与排序无关。为什么return 0; 不在int i = -3 之前执行?逻辑运算符的短路语义引入了明确定义的序列。
  • @5941 ++ 确实具有很强的优先级,但在这种情况下 j 就像if ( 0 ) ++j; 不执行++j :在你给出的表达式中++j 也永远不会执行,因为++i 为真(在逻辑表达式中,即使用逻辑运算符)并且不需要执行表达式的其余部分。优先级类似于(++i) || ((++j) &amp;&amp; (++k)),在A || B 中,如果A 为真,则不会评估B,因为它没有必要。顺便说一句,我不同意否决票:这不是一个明显的问题。
【解决方案2】:

优先级决定了操作数和运算符的分组;它不决定评估的顺序。 || 和 &amp;&amp; 强制从左到右评估; ++i 首先被评估。如果结果不为 0(例如在本例中),则根本不计算 ++j &amp;&amp; ++k。

【讨论】:

    【解决方案3】:

    这是因为逻辑运算符进行短路评估。

    一旦知道结果,就不再进行评估。

    在您的情况下,由于 ++i 的计算结果为 true 并且后跟一个或,因此甚至不再计算任何子表达式。

    “优先级”发生的情况是这样的:要计算||(最低“优先级”)的结果,编译器需要首先计算左边的结果。在您的情况下产生true,因此不需要更多计算,因为整个表达式的结果是已知的。

    如果需要评估右侧,++ 将在 || 之前评估。

    【讨论】:

      【解决方案4】:

      其他人已经解释了为什么'||'之后的部分不评估。但是,我想强调导致这种行为的标准的一个非常重要的部分。 '||'逻辑运算符充当序列点,无论同一表达式中的其他运算符如何,它都需要从左到右的评估顺序。

      引用标准ISO/IEC 9899(6.5.13/14,第 88 页)

      不同于按位 |运算符,||运营商保证 从左到右的评估;之后有一个序列点 评估第一个操作数。如果第一个操作数比较不相等 为 0,不计算第二个操作数。

      换句话说,表达式“a + b * c”与“a || b && c”不同,前者被视为一个没有序列点的表达式,而后者是一个有序列点的表达式序列点。顾名思义,序列点强制评估序列。一旦对完整表达式的结果求值(例如,当 || 的 LHS 求值为 '1'),就可以停止对表达式的进一步求值。因此,您看到的顺序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多