考虑这段代码:
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
这很有道理,但让我们快速浏览一下运算符优先级表:
据此,应该首先评估后缀运算符。现在,如果我们回到我们的代码,我们会看到 x--
应该首先被计算,但它没有。我没有考虑什么?
换句话说,如果我们严格遵循运算符优先级表,那么表达式的计算结果将是:
y =++x * 5/3 + --x;
当然,对于 y
,这给了我们一个完全不同的结果。
最佳答案
你是正确的,因为你的表达式是从左到右求值的。这是 Java 中的一般评估顺序(可能有异常(exception))。
我想你已经弄明白到底发生了什么:
x
从 3 增加到 4,并取其新值 4- 5 被评估为 5
- 4 * 5 = 20
- 取
x
的值为4进行除法;除法产生 5,x 递减为 3。 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/