【问题标题】:How is that x=20;x= ++x + ++x + x++ ;final value of x in java is 65 [duplicate]x = 20;x = ++x + ++x + x++;java中x的最终值为65 [重复]
【发布时间】:2013-10-13 12:16:50
【问题描述】:

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

当我对y= ++x + ++x + x++; 执行相同操作时,y 的值是 65,x 的值是 23。

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

【问题讨论】:

  • 后增量的优先级高于前增量。

标签: java increment operator-precedence post-increment


【解决方案1】:

你应该记住这个C Operator Precedence

所以后增量首先出现++X = 20 然后x++=22 然后 x++ = 23 总共 65 个。

【讨论】:

    【解决方案2】:

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

    但这里是基本解释。

    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.
    

    故事的寓意,永远不要这样做,并且在计算表达式之前进行预增量,在计算表达式之后进行后增量。

    【讨论】:

      【解决方案3】:

      不要在同一个表达式中对同一个变量使用++和=,增量不会生效。来自 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

      【讨论】:

      • 很好的建议,但不是问题的答案。
      【解决方案4】:

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

      ++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。

      【讨论】:

        【解决方案5】:

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

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

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

        等等。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

            ++x 与 x++ 不同

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

            在同一行中完成任何操作后,x++ 都会增加 x。

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

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

            之后,x 将是 23

            【讨论】:

              【解决方案8】:

              让 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)
              

              【讨论】:

              • 我同意 x 在第二种情况下增加到 23,但为什么它在第一种情况下不增加到 66?
              • 为什么会这样? 21 + 22 + 22 从来都不是 66。增量操作是在 x 上操作,而不是在 y 上。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-08-29
              • 2015-05-07
              • 2018-06-18
              • 1970-01-01
              • 1970-01-01
              • 2021-10-07
              相关资源
              最近更新 更多