http://introcs.cs.princeton.edu/java/11precedence/认为,增量后算子比加法算子具有更高的优先级.
因此,对于以下代码:
int i = 1;
int j = i + i++;
System.out.println(j);我认为分配给j的表达式将按以下方式进行计算(每一行都是计算中的“步骤”):
i + i++
i + (1) // do post-increment operator; returns 1, and makes i = 2
(2) + (1) // do addition operator. need to get the operand i, so do that.
3但是当我尝试这个程序时,j的值是2。
所以我很困惑。在表达式中,它是否将表达式中的所有“i”替换为当前值i,甚至在触摸i++之前?
编辑:这里的人使用的短语“评估顺序”帮助我找到了以下可能有用的堆栈溢出答案:Java中计算顺序的规则是什么?。
编辑:我对下面的答案做了最好的猜测。我仍然欢迎对它的修正。
发布于 2016-10-24 13:51:10
编辑:我不完全理解别人给出的答案,但这是我对正在发生的事情最好的猜测。如果有人想纠正这一猜测,请这样做。
我的最佳猜测是:a + b * c (其中a、b和c是变量)被构造成表达式树,其中优先级最低的操作符位于树的顶部:
+
/ \
a *
/ \
b c现在,对这棵树的求值方式如下:+操作符得到求值。为此,它(递归)计算左子树及其右子树,然后添加这些值。
总的来说,这就是所发生的事情:
- addition operator gets evaluated.
it says "evaluate my left subtree, then my right subtree,
then add them together. i return that value"
- left subtree: is a. evaluate variable a into a value.
(that is, get the value of variable a.)
- right subtree: i'm a multiplication operator. to evaluate me,
evaluate my left subtree, then my right subtree, the nmultiply
them togeter. i return that value.
- left subtree: is variable b. evalute that.
- right subtree: is variable c. evaluate that.这就是为什么a首先完成其评估,然后是b,然后是c,然后是b * c,然后是a + (b * c)。
在带有++i的表达式中,也会发生同样的事情。例如,对于++i + i++,表达式树如下所示:
+
/ \
preinc postinc
| |
i i其中(例如) preinc指的是增量前运算符(而预增量运算符恰好有一个操作数:变量)。这里的区别是,当以preinc作为根的子树需要得到计算时,“计算preinc运算符树”并不意味着“用变量的值替换变量”(例如,2+ i ),而是意味着“在变量i中增加值,然后preinc(i)的值是变量i中的新值”。
以类似的方式,赋值运算符=的工作方式与2+ i略有不同。
int j;
j = 3;这里的表达式树是
=
/ \
j 3当一棵以赋值操作符作为根的树需要被求值时,这意味着“左手操作符必须是一个变量--而不是一个值!然后计算右边的子树(我们期望它将它求值为一个值),然后将该值放在左子树中的变量中。现在,由=(j,3)返回的值是右边子树中的值”。
有了这个猜测,我就能够正确地给出(链接为:https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.7)中给出的例子的答案。
也就是说,如果我绘制表达式树,下面两个示例是可以由我解决的:
示例:
int i = 2;
int j = (i = 3) * i;
System.out.println(j);示例:
int b = 9;
b = b + (b = 3);
System.out.println(b);发布于 2016-10-07 21:10:09
发布于 2016-10-07 21:26:32
Post增量--首先使用以前的变量值,然后使用增量。
预增量-首先递增,然后使用新的变量值。
int i = 1;
int j = i + i++;
System.out.println(j);// 2
System.out.println(i);// 2在这里,我首先用先前的i值i,e,e,+替换,再用i的旧值,这样j就变成2,然后我被增加到2。
现在考虑一下下面的代码
int i = 1;
int j = i++ + ++i;
System.out.println(j);// 4
System.out.println(i);// 3在这里,首先我是增量(预),所以我变成2,然后我被取代,e,j=2+2,现在j值将是4,再一次我增加(post) 1,所以我的当前值是3。
https://stackoverflow.com/questions/39925647
复制相似问题