【问题标题】:Why the output won't be this in the code? [duplicate]为什么代码中的输出不是这个? [复制]
【发布时间】:2015-09-24 18:24:55
【问题描述】:
#include <stdio.h>

int main(void) {
int i = -3, j = 2, k = 0, m;
m = ++i && ++j || ++k;
printf("%d %d %d %d\n",i,j,k,m);
    return 0;
}

我正在尝试了解 C 中运算符的关联性和优先级。在这里,输出结果是 -2 3 0 1,但我认为输出应该是 -2 3 1 1,因为 k 也是预先递增的。为什么这不是答案?谢谢!

【问题讨论】:

  • 为什么要浪费时间执行||之后的命令什么时候之前的陈述已经成立?
  • 哇!找了好久也没找到,不然一开始就不会发这个问题了。无论如何,无需投票,是的,很好的答案。 :)
  • 教科书和/或网页中没有解释代码吗?你为什么要我们解释它,(再次,再次)?

标签: c operator-precedence


【解决方案1】:

|| 具有短路评估,这意味着仅当左侧为 false 时才评估右侧。在您的情况下,这不会发生,因为 ij 在递增后具有不同于 0 的值,因此 ++k 不会被执行

当您有一个 &amp;&amp; 时,会发生相同的行为,其中 LHS 表达式的计算结果为 false

【讨论】:

  • 只有|| 运营商会发生这种情况,还是其他任何运营商也是如此?像 &amp;&amp; 一样,如果 LHS 是 0false,那么不会评估 RHS?
  • 对于&&也是如此,谢谢指出,我会编辑我的答案!
  • 并且,如果它也发生在任何其他运算符上,也请添加。谢谢! :)
  • @JohnLui:每个 logic 运算符都是如此。它不适用于算术和按位布尔运算符。
【解决方案2】:

|| 之前的表达式为真,因此|| 之后的部分即 ++K 不会被执行,因此k 不会递增。因此,K 的值保持为 0,m 的值为 1,因为 || 的左侧为真,true || &lt;anything&gt; 始终为 true

【讨论】:

    【解决方案3】:

    1 || 0 = 11 || 1 = 0

    因此,在使用 || 运算符评估语句时,一旦第一个条件为 TRUE,则无需评估此处发生的第二个表达式。

    【讨论】:

      【解决方案4】:

      不要与Precedence and Order of evaluation 混淆。

      逻辑OR||的求值顺序是从左到右。

      所以如果left = true 那么left || right 将永远不会执行right。在您的代码中发生了完全相同的情况。

      如您所知,在 C 中任何非零值都被视为 true,因此,++i-2true。所以,

       m = ++i && ++j || ++k;
       m = (true && true) || bla bla bla; //right not even checked!
       m = true 
       m = 1
      

      你得到了预期的输出。

      对于实验,而不是i = -3尝试i = -1,那么场景将是

       m = ++i && ++j || ++k;
       m = false && (not going to evaluate) || ++k;
       m = false || true;
       m = true 
       m = 1
      

      输出将是:0 2 1 1

      【讨论】:

      • 等等,我明白了你的意思,但是,由于&amp;&amp; 的优先级高于||,因此不会先执行,然后将其结果用于评估||
      • 哦!对不起,明白了。答案清楚地解释了我的疑问。不过感谢您的帮助。 :)
      • @JohnLui Precedence 仅保证表达式本身将被评估为((++i) &amp;&amp; (++j)) || ...。但这与每个运算符的操作数被求值的顺序无关!以简单的数学计算,1 + 2 + 3 * 4 保证等于1 + 2 + (3 * 4),但优先规则并没有告诉您必须在计算1+2 之前开始计算3*4。你也可以反过来做。数学不在乎,因为你会得到相同的结果。然而,在 C 编程中,两种不同的求值顺序可能会导致不同的结果。
      猜你喜欢
      • 2020-03-14
      • 1970-01-01
      • 2016-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 1970-01-01
      相关资源
      最近更新 更多