【问题标题】:Parentheses and logical operators括号和逻辑运算符
【发布时间】:2012-10-01 11:52:29
【问题描述】:

考虑一下这段代码(C++):

int x = -4 , y = 5 ;
bool result = x > 0 && y++ < 10 ;

表达式 (x > 0) 将首先被评估,因为 (x > 0 = false) 和由于短路评估,另一个表达式 (y++

现在考虑以下代码:

int x = -4 , y = 5 ;
bool result = (x > 0) && (y++ < 10) ;

预计括号中的表达式将首先被计算,以便在执行逻辑与之前,表达式 (y++

这个案例的解释是什么?!

【问题讨论】:

  • “预计括号中的表达式将首先被计算” -- 错误。括号没有区别,x &gt; 0 在这两种情况下总是首先被评估。
  • 括号可以覆盖优先级,但order of evaluation is independent of precedence。评估顺序由序列点 (C, C++98/03) 或排序约束 (C++11) 决定,而不是优先级或关联性。
  • 除非出现 &&,否则永远不会评估右侧。虽然您认为应该首先在数学中评估括号是正确的,但布尔逻辑有点不同,因为它保证从左到右。

标签: java c++ logical-operators short-circuiting


【解决方案1】:

即使有括号短路必须仍然发生。考虑是否有一个涉及指针的表达式:

int* ptr = 0;
int bar = 5;
bool result = (ptr != 0) && (*ptr == bar || bar > 10);

您显然无法安全地评估 &amp;&amp; 的右侧,但需要括号才能使优先级按预期工作。括号只是确定操作的顺序实际执行而不是它们以特定顺序发生。

【讨论】:

    【解决方案2】:

    左侧判断结果时,右侧不求值。

    在第一种情况下,右侧是y++ &lt; 10,并且不对其进行评估。第二种情况,右边是(y++ &lt; 10),这个不求值。

    没有规则首先计算括号中的表达式。括号仅分组操作数。

    【讨论】:

      【解决方案3】:

      解释在问题中 - 短路

      在 C++ 中,&amp;&amp;(以及||)的评估保证是从左到右的,一旦遇到false(分别为true 用于||) , 评估保证停止。

      我猜 Java 也类似。

      括号是多余的,在这种情况下不相关 - 它与运算符优先级无关。它只是与&amp;&amp; 的工作方式有关:

      其实就是两个版本

      x > 0 && y++ < 10
      (x > 0) && (y++ < 10)
      

      是等价的,因为++的优先级最高,其次是&lt;,&gt;,最后是&amp;&amp;。学究式地,你应该把它写成:

      (x > 0) && ((y++) < 10)
      

      5.14 逻辑与运算符 [expr.log.and]

      1 &amp;&amp; 运算符从左到右分组。操作数都被隐式转换为 bool 类型(第 4 条)。结果 如果两个操作数都是 truefalse 否则为真。 与 & 不同,&& 保证从左到右求值:第二个 如果第一个操作数是 false,则不计算操作数。(强调我的)

      【讨论】:

      • 仅供参考,Java 具有非短路 AND (&amp;) 和 OR (|)。
      • @SteveKuo 这些是位运算符,C++ 版本也是非短路的。
      猜你喜欢
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2020-12-20
      • 1970-01-01
      • 2014-05-10
      相关资源
      最近更新 更多