1

这怎么可能,因为后增量运算符应该将 x 增加到 66?

当我为它做同样的事情时,y= ++x + ++x + x++;它给出了一个值 65y和 23 x

所以让我知道 java 编译器是如何解决这些表达式的。

4

8 回答 8

3

让 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)
于 2013-10-07T02:14:32.033 回答
1

++x 与 x++ 不同

++x 在同一行中完成任何操作之前递增 x。

x++ 在同一行中完成任何操作后递增 x。

要计算到 65,它必须进行如下计算。

(1+20)+(1+21)+(22)= 65

之后,x 将是 23

于 2013-10-07T02:17:17.967 回答
0

总的来说,这是一种糟糕的编程,永远不应该在实际代码中使用,因为它很容易在所有的前后增量中迷失。

但这里是基本解释。

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.

故事的道德,永远不要这样做,并且在评估表达式之前发生预增量,并且在评估表达式之后发生后增量。

于 2013-10-07T05:09:50.027 回答
0

我认为 y= (++20) + (++21) + 22 = 21 + 22 +22 = 65

于 2013-10-07T02:17:40.587 回答
0

首先,你应该明白这一点:

++i递增i和返回i

i++返回i然后递增它。

现在我们已经建立了这个,让我们分解程序。

在您的程序开始时,x = 20. 因此,++x将返回 21。现在,当您x再次以这种方式递增时,您将递增21而不是20。因此,++x+++x将评估为21 + 22which 等于 43。此时在程序中,x等于22。因此,如果您添加x++到 43,您会将 的值添加到 43,x然后才会递增x。这最终导致y值为 65,x值为 23。

于 2013-10-07T02:17:59.000 回答
0

不要在同一个表达式中对同一个变量使用 ++ 和 =,增量不会生效。摘自 Java™ Puzzlers: Traps, Pitfalls, and Corner Cases 作者 Joshua Bloch,Neal Gafter Puzzle #25:

正如这个谜题的标题所暗示的,问题在于执行增量的语句:

j = j++;

据推测,该语句的作者打算将 j 的值加 1,这就是表达式 j++ 所做的。不幸的是,作者无意中将这个表达式的值赋回了 j。当放置在变量之后时,++ 运算符用作后缀递增运算符 [JLS 15.14.2]:表达式 j++ 的值是 j 在递增之前的原始值。因此,前面的赋值首先保存 j 的值,然后将 j 设置为其值加 1,最后将 j 重置回其原始值。换句话说,赋值等价于以下语句序列:

诠释 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

于 2013-10-07T02:20:38.097 回答
0

所以让我知道 java 编译器是如何解决这些表达式的。

Java 编译器只是实现 Java 语言规范。

如果您真的需要了解编译器如何评估这样可怕和怪异的语句,您需要了解规范的相关部分:

等等。

于 2013-10-07T02:21:15.420 回答
0

你应该记住这个C 运算符优先级

所以后增量先行, ++X = 20 然后总共 65。x++=22x++ = 23

于 2016-03-31T18:32:41.973 回答