【问题标题】:is the precedence of operator ignored in 'if' conditions是“if”条件中忽略的运算符的优先级
【发布时间】:2013-05-17 11:57:53
【问题描述】:

我有以下代码:

void main()
{
  int k, x, y, z;
  printf("\nExperiment 1:");
  x = 0, y = 0, z = 0;
  k = x++ || y++ && z++;
  printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k);
  printf("\nExperiment 2:");
  x = 1, y = 0, z = 0;
  k = x++ || y++ && z++;
  printf("\nx = %d, y = %d, z = %d and k = %d\n", x, y, z, k);
}

输出:

实验 1: x = 1, y = 1, z = 0 和 k = 0

实验 2: x = 2,y = 0,z = 0 和 k = 1

我的理解是: 要使表达式为真,'||' 的左侧或右侧必须非零。它从左边开始。如果 left 不为零,则不会进一步评估。如果为零,则从右侧开始。在右边我们有'&&'。因此,我们再次从 && 的左侧开始,如果它为零,则表达式不能为真并且不会继续。否则,它会评估 '&&' 的右侧

我的假设是运算符 && 具有更高的优先级。所以,它的两个参数都应该被评估,然后 && 应该被应用在它上面,然后评估 || 的两个参数。

编译器是否在优化自己?我使用了禁用优化的 Visual Studio TC 编译器。

【问题讨论】:

  • 顺便说一句,这些不是“如果条件”。它们只是表达式,使用布尔运算符和后自增运算符。
  • 仅仅因为 && 具有更严格的优先级并不意味着 k = x++ || (y++ && z++) 将在 || 之前执行 &&。这称为短路并且众所周知。你甚至自己提到它。想象一下:k = x++ || f(&y,&z) 其中 f() 返回 (*y)++ && (*z)++。它在功能上等同于您的代码。
  • @Matthias:确实; ++ 的优先级甚至高于 &&;我们不希望仅仅因为优先级而在其他所有事情之前发生后递增......
  • 你在哪里收到void main()?在几乎所有情况下都应该是int main(void)
  • 只是为了强化概念,措辞略有不同:优先级仅控制运算符和操作数的分组。它控制评估顺序。

标签: c operator-precedence


【解决方案1】:

我认为§6.5.14 Logical OR operator(我的重点)在 C11 中对此进行了介绍

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

【讨论】:

    【解决方案2】:

    所以表达

    k = x++ || y++ && z++;
    

    被解释为(由于优先规则):

    k = x++ || (y++ && z++);
    

    在实验 1 中,我们有x = y = z = 0;

    在实验 2 中,我们有x = 1, y = z = 0;

    因此,右侧表达式在评估 y++ 后停止,因为它的值为 0,因此布尔值不能变为真。

    【讨论】:

      猜你喜欢
      • 2020-08-22
      • 2012-12-09
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 2015-03-20
      • 2021-10-25
      • 2017-10-13
      相关资源
      最近更新 更多