【问题标题】:Logical Operator Precedence逻辑运算符优先级
【发布时间】:2013-05-28 05:20:48
【问题描述】:

通过Java运算符优先级表:

'|'逻辑 OR 运算符的优先级高于 '&&' 逻辑 AND 运算符。

我使用以下代码检查了上述事实

int y = 5;
int x = 2;
if(  x++  >  2  &&   ++y  >  2  |  true    )
; //do nothing
System.out.println("x = " + x + " y = " + y);

但在上面给出的输出为 -

x = 3 y = 5

表明 x++ 正在首先评估。

即使我把括号放在条件周围 |

if(  x++  >  2  &&   (++y  >  2  |  true) )
;

但我仍然得到相同的输出。

为什么运算符优先级在这种情况下不起作用?

【问题讨论】:

    标签: java


    【解决方案1】:

    这不是逻辑运算符。这就是位运算符。它将评估所有内容 - 也就是说,它不会短路 - 如果有任何东西将该位翻转为 1,它将保持在 1 直到被否定。

    以下是这些语句的评估方式:

    • x++ > 2 && ++y > 2 || true -> true。我们使用逻辑 AND 失败,但使用逻辑 OR 成功。对于短路,我们不会继续评估逻辑与的任何部分,因为x > 2 为假。

    • x++ > 2 && (++y > 2 || true) -> false,因为x > 2 不真实,我们会短路。

    如果您实际上不想要短路行为,那么也可以使用按位与,您将获得预期的评估块。

    x++ > 2 & ++y > 2 | true 仍将计算为 true,但 x y 的值将分别更改为 36

    【讨论】:

    • 其实我用过 |运营商故意,如果 |运算符的优先级高于 &&,那么为什么 && 比 | 优先执行。
    • 我不这么认为。您在逻辑 AND 的任一侧应用所有按位运算,然后应用逻辑 AND。你也得到了一点红鲱鱼 - 你实际上没有在逻辑块中任何事情,所以你怎么能绝对确定你没有得到你想要的结果?跨度>
    • 因为如果 |在 && 之前求值,那么 y 应该有 6 作为输出。
    • 没有。你在&& 上短路了。不评估右侧。
    【解决方案2】:

    | 是按位或运算符。您正在寻找||。它类似,但不同之处在于它具有更高的优先级并且不应用短路评估。

    我明白你现在真正在问什么了。您想知道为什么如果 && 的优先级最低,那么在最终到达之前不会评估语句的其余部分。所以在

    x++  >  2  &&   ++y  >  2  |  true 
    

    它应该评估x++ > 2,然后是++y > 2 | true,最后应用&&。嗯,答案是&& 应用短路评估。当然,它可以评估所有内容,然后应用其效果,这就是位运算符的作用。然而并不是因为

    if (a && b && ...)
    

    应该表现得与

    相似
    if (a) {
       if (b) {
          ...
       }
    }
    

    运算符优先级如您所愿,但是由于运算符的属性,评估提前终止。所以回到

    x++  >  2  &&   ++y  >  2  |  true 
    

    我们看到x++ > 2 是假的,所以++y > 2 | true 没有被评估。

    【讨论】:

    • 不是我找的 |操作员。如果 |运算符的优先级高于 &&,而不是 && 的执行优先于 |。
    • @VijendraSingh 我现在明白你的意思了。我已经编辑了我的答案。
    • @ZongLi 你可以展示如何用括号解析代码。 (x++ > 2) && (++y > 2 | true).
    【解决方案3】:

    试试这个

    if(  x++  >  2  &&   ++y  >  2  ||  true    )
    

    您使用的是bitwise 运算符而不是logical 运算符

    Operators in java

    【讨论】:

      【解决方案4】:

      即使运算符 | 具有更高的优先级,即使在程序检查是否需要计算右侧(&&)时,也不会发现运算符。

      考虑声明(true && true | true)。它是这样计算的:

      1. 检查(true && ...) 以查看是否需要进一步操作(确实如此)。
      2. 更高的优先级:执行操作(true | true) -> true
      3. 低优先级:执行操作(true && true) -> true

      在你的例子中,由于(x++ > 2) 给出了false&& 的右侧甚至都不会被触及。

      【讨论】:

        【解决方案5】:

        因为无论你放置大括号,它都会从左到右开始,因为 在 && 的情况下,它被优化为检查第一个条件,它得到 false,那么为什么要进入第二个条件,不管大括号有没有,其次 x++ 将被执行,条件为 false ,所以它打印相同的输出但是当你说使用 ||

        class Test{
        public static void main(String[] args) {
        
            int x=2,y=5;
            if(  x++  >  2  ||   (++y  >  2  |  true) )
                ;
        
            System.out.println(x +" "+y  );
        
        }   
        }
        

        它将打印3 6 因为||发生时,第一个条件为假,但当涉及到第二个时,++y > 2 评估为真 |在布尔值之间根据位或给出输出,true OR true 为真。

        【讨论】:

          【解决方案6】:

          逻辑运算符:(&&、||、&、| 和 ^)只能用于计算两个 布尔表达式。

          && 和 & 的区别在于 && 运算符 如果左边的计算结果为假,则不会费心测试右边的操作数,因为 && 表达式的结果永远不会为真。

          || 的区别和 |是 那个||如果左侧计算为 为真,因为此时结果已为真。

          位运算符:(&、| 和 ^)也可以称为“位”运算符。位运算符逐位比较两个变量,并返回一个变量 其位已根据被比较的两个变量是否具有 分别为“on”(&)、一个或另一个“on”(|)或完全 一个“开”(^)。

          【讨论】:

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