【发布时间】:2013-10-13 12:16:50
【问题描述】:
这怎么可能,因为后自增运算符应该将 x 增加到 66?
当我对y= ++x + ++x + x++; 执行相同操作时,y 的值是 65,x 的值是 23。
所以让我知道 java 编译器是如何解决这些表达式的。
【问题讨论】:
-
后增量的优先级高于前增量。
标签: java increment operator-precedence post-increment
这怎么可能,因为后自增运算符应该将 x 增加到 66?
当我对y= ++x + ++x + x++; 执行相同操作时,y 的值是 65,x 的值是 23。
所以让我知道 java 编译器是如何解决这些表达式的。
【问题讨论】:
标签: java increment operator-precedence post-increment
你应该记住这个C Operator Precedence
所以后增量首先出现++X = 20
然后x++=22 然后
x++ = 23 总共 65 个。
【讨论】:
总的来说,这是一种糟糕的编程,永远不应该在实际代码中使用,因为它很容易迷失在所有的前后增量中。
但这里是基本解释。
simple enough:
x = 20
Here is where it gets messy:
y = ++(20) + ++(++(20)) + (++(++(20)))++
Pre increment --> ++x
Post increment --> x++
Pre increments happen inside the evaluation and post
increments happen after the evaluation.
So that statement can be reduced in the following steps.
y = 21 + ++(21) + (++(21))++
y = 21 + 22 + (22)++
y = 21 + 22 + 22
y = 65
After all these increments x = 23. In the statement above though, x equals multiple
numbers because of all the pre and post increments.
故事的寓意,永远不要这样做,并且在计算表达式之前进行预增量,在计算表达式之后进行后增量。
【讨论】:
不要在同一个表达式中对同一个变量使用++和=,增量不会生效。来自 Java™ Puzzlers: Traps, Pitfalls, and Corner Cases 作者 Joshua Bloch, Neal Gafter 谜题 #25:
正如谜题的标题所示,问题在于执行增量的语句:
j = j++;
据推测,该语句的作者打算将其加 1 到 j 的值,这就是表达式 j++ 所做的。不幸的是, 作者无意中将此表达式的值赋回给 j。 当放置在变量之后时,++ 运算符用作后缀 自增运算符 [JLS 15.14.2]:表达式 j++ 的值为 j 增加之前的原始值。因此, 前面的赋值首先保存 j 的值,然后将 j 设置为其 值加 1,最后将 j 重置为其原始值。在 换句话说,赋值等价于这个序列 声明:
int tmp = j;
j = j + 1;
j = tmp;
因此,您的母鹿在评估时看起来像这样:
int x=20
int sum;
x=x+1; //x=20=1
sum=x; //sum and x equal 21
x=x+1; //x=22
sum=sum+x; //sum=43
sum= sum+x; //sum=65
x= x+1; //x=23
x=sum; //x=65;
这就是为什么 x=65 而不是 66
【讨论】:
首先,你应该明白这一点:
++i 递增 i 并返回 i。
i++ 返回i,然后将其递增。
现在我们已经建立了这个,让我们分解程序。
在程序开始时,x = 20。因此,++x 将返回 21。现在,当您再次以这种方式递增 x 时,您将递增 21 而不是 20。因此,++x + ++x 将计算为 21 + 22,等于 43。此时,在程序中,x 等于 22。因此,如果将 x++ 添加到 43,您会将 x 的值添加到 43,然后才会增加 x。这最终导致 y 的值为 65,x 的值为 23。
【讨论】:
所以让我知道 java 编译器是如何解决这些表达式的。
Java 编译器只是在实现 Java 语言规范。
如果您真的需要了解编译器如何评估此类可怕和怪异的语句,您需要了解规范的相关部分:
等等。
【讨论】:
我认为 y= (++20) + (++21) + 22 = 21 + 22 +22 = 65
【讨论】:
++x 与 x++ 不同
++x 在同一行中执行任何操作之前递增 x。
在同一行中完成任何操作后,x++ 都会增加 x。
要计算到 65,它必须进行如下计算。
(1+20)+(1+21)+(22)= 65
之后,x 将是 23
【讨论】:
让 Java 向您展示。 javap -c MyClass 显示字节码:
public static void main(java.lang.String[]);
Code:
0: bipush 20
2: istore_1
3: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
6: iinc 1, 1
9: iload_1
10: iinc 1, 1
13: iload_1
14: iadd
15: iload_1
16: iinc 1, 1
19: iadd
20: dup
21: istore_1
22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
25: return
如果你仔细想想,结果是完全合乎逻辑的:你有两个前置增量和一个后置增量。所以,你的代码是有效的:
y = 0
x++ // 21
y += x
x++ // 22
y += x
y += x // (still 22!)
x++ // 23
x = y // (21 + 22 + 22 at this point)
【讨论】: