考虑以下代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
它评估如下:
x is 2
y is 7
Run Code Online (Sandbox Code Playgroud)
这很有道理,但让我们快速查看运算符优先级表:
据此,应该首先评估后缀运算符.现在,如果我们回到我们的代码,我们将看到x--应该首先评估,但事实并非如此.我不记得什么?
换句话说,如果我们严格遵循运算符优先级表,那么表达式将计算为:
y = ++x * 5 / 3 + --x;
当然,这给了我们一个完全不同的结果y.
你的表达从左到右评估是正确的.这是Java中的一般评估顺序(可能有例外).
我想你已经弄清楚到底发生了什么:
x 从3增加到4并获取其新值4x4 的值用于除法; 除法得到5,x递减到3.x 在最终加法的值之前进一步递减到2,然后得到7.除外:只有在可以保证结果相同的情况下,才允许编译器交换步骤.因此我们知道结果只能是7.
尝试将两个概念区分开来:评估顺序和运算符优先级.他们不一样.
优先表告诉你表达式被理解为((++x) * 5 / (x--)) + (--x)(这大部分是好的,因为++(x * 5 / x)-- + --x无论如何都没有意义).
举一个不同的例子:f(x) - g(x) * h(x).该mehtods被称为左到右: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);
}
}
Run Code Online (Sandbox Code Playgroud)
这打印:
p(): 4
p(): 4
p(): 2
x is 2
y is 7
Run Code Online (Sandbox Code Playgroud)
所以是的,两点x被评估为4.
| 归档时间: |
|
| 查看次数: |
589 次 |
| 最近记录: |