【问题标题】:Why is the output different in case of &&, &, ||?为什么在 &&, &, || 的情况下输出不同?
【发布时间】:2011-03-27 06:42:38
【问题描述】:

这里是代码段

你能解释一下为什么输出会变化吗

1)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t && ((i++) == 0));
        b = (f && ((i+=2) > 0));
        System.out.println(i);      
    }
}

本例中的输出为 1

2)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t & ((i++) == 0));
        b = (f & ((i+=2) > 0));
        System.out.println(i);      
    }
}

这种情况下的输出是 3

3)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t || ((i++) == 0));
        b = (f || ((i+=2) > 0));
        System.out.println(i);      
    }
}

本例中的输出为 2

4)

public static ShortCkt {
    public static void main(String args[]) {
        int i = 0;
        boolean t = true;
        boolean f = false, b;
        b = (t | ((i++) == 0));
        b = (f | ((i+=2) > 0));
        System.out.println(i);      
    }
}

这种情况下的输出是 3

【问题讨论】:

    标签: java operators


    【解决方案1】:

    为什么&&,&,||的情况下输出不同?

    就像在 C/C++ 中一样,&& 被“惰性”评估,而 & 不是。

    如果a 为假,那么a && b 将返回假而不评估b

    a || b 也是如此:如果第一个操作数 a 为真,则整个表达式为真,第二个操作数 b 永远不会被计算。但是,对于 a | bab 都将被评估。

    如果在使用&&(或||)时未评估的操作数具有副作用,如您的示例所示,则会产生后果。


    旁注:很少有 Java 程序员知道 ^ (xor) 也适用于布尔值。 (^^ 版本不存在只是因为它是多余的。)

    【讨论】:

      【解决方案2】:

      我们在这里关注 4 个boolean 二元运算符:

      • && 是条件和运算符
        • & 是逻辑与运算符
      • || 是条件或运算符
        • | 是逻辑或运算符

      这里是重点:

      • “条件”表示短路:如果不影响运算结果,则不计算正确的操作数
      • “逻辑”不会短路:它计算两个操作数,先左后右。
      • 只有当两个操作数都是true时,“and”的结果才是true
        • 如果左操作数是false,则无论右操作数如何,结果都是false
      • 仅当至少一个操作数为true 时,“或”的结果为true
        • 如果左操作数是true,则无论右操作数如何,结果都是true

      换句话说,假设没有例外等:

      • &| 总是计算两个操作数
      • &&||有条件地评估右操作数;只有当右操作数的值会影响二元运算的结果时,才会计算右操作数。这意味着在以下情况下不评估右操作数:
        • && 的左操作数计算结果为 false
          • (因为无论右操作数计算为什么,整个表达式都是false
        • || 的左操作数计算结果为 true
          • (因为无论右操作数计算为什么,整个表达式都是true

      参考文献

      另见

      相关问题

      【讨论】:

        【解决方案3】:

        &| 运算符是按位的,因此必须先计算表达式的两边,然后才能使用运算符,因此在情况 2 和 4 中,运算符的两边总是 em> 已评估。

        情况1和3的区别在于短路逻辑。

        在情况 1 中,第二个表达式中的 && 运算符在第一个 false 上短路为 false,导致表达式的后半部分不被计算。

        在情况 3 中,第二个表达式前半部分中的 false 导致表达式后半部分的计算,增加 ifalse || expr 只能是 false 如果 expr 也是假的(所以它必须被评估)。

        【讨论】:

          【解决方案4】:

          这是因为 && 和 ||是“短路机制”的逻辑运算符。如果你使用 ||并且第一个表达式的计算结果为 true,第二个表达式不会被计算,因此 i 不会被更新。 & 和 |是对输入进行位计算的位运算符。它们没有短路,因此无论如何都会评估整个表达式。

          【讨论】:

            【解决方案5】:

            &&|| 是逻辑 AND 和 OR 运算符,它们总是产生 boolean 表达式。 &| 是按位 AND 和 OR 运算符,它们对每一侧进行按位比较。有关这些运算符的详细信息,请参阅this link

            【讨论】:

            • &| 也可以是 boolean。但不,DV 不是我。
            • @poly 好点 - 因为这个原因,我没有为 &| 指定结果类型,就像我对逻辑运算符所做的那样。不过,我应该明确说明这一点。
            猜你喜欢
            • 2015-11-27
            • 2017-09-22
            • 1970-01-01
            • 2019-01-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-07-27
            相关资源
            最近更新 更多