java - 表达式与运算符优先级的从左到右求值。为什么从左到右的评估似乎胜出?

标签 java

考虑这段代码:

public class Incrdecr {

static int x = 3;
static int y = ++x * 5 / x-- + --x;

public static void main(String[] args){

    System.out.println("x is " + x);
    System.out.println("y is " + y);
}

它的计算结果如下:

x is 2
y is 7

这很有道理,但让我们快速浏览一下运算符优先级表:

enter image description here

据此,应该首先评估后缀运算符。现在,如果我们回到我们的代码,我们会看到 x-- 应该首先被计算,但它没有。我没有考虑什么?

换句话说,如果我们严格遵循运算符优先级表,那么表达式的计算结果将是:

y =++x * 5/3 + --x;

当然,对于 y,这给了我们一个完全不同的结果。

最佳答案

你是正确的,因为你的表达式是从左到右求值的。这是 Java 中的一般评估顺序(可能有异常(exception))。

我想你已经弄明白到底发生了什么:

  1. x 从 3 增加到 4,并取其新值 4
  2. 5 被评估为 5
  3. 4 * 5 = 20
  4. x的值为4进行除法;除法产生 5,x 递减为 3。
  5. x 在其值用于最终加法之前进一步减为 2,然后产生 7。

异常(exception):编译器只有在保证结果相同的情况下才允许交换步骤。因此我们知道结果只能是7。

尽量区分两个概念:求值顺序和运算符优先级。它们不一样。

优先级表告诉您表达式被理解为 ((++x) * 5/(x--)) + (--x)(这主要是因为 ++(x * 5/x)-- + --x 无论如何都没有意义。

举一个不同的例子:f(x) - g(x) * h(x)。从左到右调用方法:f(),然后是 g(),最后是 h()。优先级表只告诉你乘法先于减法。

编辑:Lew Bloch 在评论中质疑 x 在计算过程中的任何时候都会被评估为 4。为了对此进行测试,我根据问题对您的程序做了以下变体:

public class Incrdecr {

    static int x = 3;
    static int y = p(++x) * 5 / p(x--) + p(--x);

    private static int p(int i) {
        System.out.println("p(): " + i);
        return i;
    }

    public static void main(String[] args) {
        System.out.println("x is " + x);
        System.out.println("y is " + y);
    }
}

这打印:

p(): 4
p(): 4
p(): 2
x is 2
y is 7

所以是的,在两个点上 x 的计算结果为 4。

关于java - 表达式与运算符优先级的从左到右求值。为什么从左到右的评估似乎胜出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42793018/

相关文章:

java - 防止过度沮丧

java - 如果两者都被评估,比较文字的顺序是否重要?

java - 如何在 JPA 实体中将字段设置为可选字段?

java - 首先在 Object.property1 上对 Map<String, Object> 进行排序,然后对于每个 Object.property1,按 Object.property2 排序

java - 使用java删除文件

Java 无法在 MacOS X Leopard 上运行

构造函数中的 Java 条件以调用父构造函数

Java公共(public)枚举方法目的

java - OWASP ZAP : Active Scanner in Continuos Integration

java - 整个工作集/工作区的 Eclipse “Open Call Hierarchy”