【问题标题】:java operator ++ problemjava运算符++问题
【发布时间】:2011-10-20 05:11:54
【问题描述】:

我想知道为什么第一个代码输出是 000 而第二个是 123

第一个:

int z=0;
    while(z<4)
    {
       z=z++;
       System.out.print(z);

    }

第二个:

int z=0;
int x=0;
    while(z<5)
    {
       x=z++;
       System.out.print(x);

    }

这两个代码有什么不同,为什么第一块不增加z的值?

【问题讨论】:

  • 第一个代码将永远循环,第二个将打印01234
  • @The Scrum Meister:那个错误让我无法回答:(

标签: java operators


【解决方案1】:
z=z++;

这意味着首先将z的值(位于右侧)分配给z(位于左侧),然后在右侧进行增量(没有用)。

【讨论】:

  • 简单一行,方便用户理解。但我认为这让你感到困惑,所以你应该做一个练习并学习。
  • 简单一行,方便用户理解。但我认为它让你感到困惑,所以你应该做一个练习并学习。以上评论是针对“邓肯”的。
  • @Duncan:如果没有新的东西并不意味着你应该投反对票并且回答也没有错。所以我建议你不要总是太聪明,你应该阅读和理解。
  • @Duncan:如果你想成为一个好人,你应该成为一个好的倾听者和阅读者,但你不是。你过于自信,总是低估别人。 (你证明了)。我希望你有一天会明白这一点。美好的一天,再见
【解决方案2】:

记住这一点,Java 评估您的表达式从右到左(就像 C 和 C++),

所以如果你的代码是这样的

z = z++

那么如果在这一行执行之前z为0,会发生什么:

  1. z++ 被评估为表达式,返回值 0
  2. 然后z 因 ++ 运算符而递增,其值为 1。
  3. 现在左边的z 被赋值为z = (value returned by z++)
  4. 由于z++返回的值为0,所以z被重置为0。

需要注意的重要一点是,z++ 中固有的赋值结果是在更新左侧的 z 变量之前评估

【讨论】:

    【解决方案3】:

    我想这会给你一个很好的解释。

    考虑这个类:

    public class T
    {
        public void f() {
        int count = 0;
        count = count++;
        }
    }
    

    这是相关的字节码:

    public void f();
      Code:
       0:   iconst_0
       1:   istore_1
       2:   iload_1
       3:   iinc    1, 1
       6:   istore_1
       7:   return
    }
    
    1. iconst_0 将常量 0 加载到堆栈上(这是为变量 count 赋值为 0
    2. istore_1 将堆栈值(现在是0)存储到变量 1 中
    3. iload_1 将 int 值从变量 1(现在是 0)加载到堆栈中
    4. zinc 1, 1 增加 1 变量 1(count = 1 现在)
    5. istore_1 将堆栈值(0 现在从第 3 步开始)存储到变量 1 中
    6. 返回

    现在应该很清楚count = count++ 是如何用Java 编译的。

    【讨论】:

      【解决方案4】:

      如果你写的是foo = foo++ 之类的东西,那你就错了。一般来说,如果你看到像x = x++ + ++x; 这样的表达式,那就是严重错误。无法预测如何评估这种类型的表达式。在像C 这样的语言中,可以根据实现者的需要评估这些表达式。

      我强烈建议您使用++ 运算符,因为您在阅读代码时一定会遇到它。

      正如其他人指出的那样,x++ 是后缀运算符,++x 是前缀运算符。

      int x = 0;
      int y = x++; // y=0, x=1
      int z = ++x; // z=2, x=2
      

      请注意,yzx 的值仅是在计算表达式之后。它们在执行期间是什么是未定义的。

      因此,如果您看到类似 foo(x++, ++x, x) 的代码,请奔向小山。

      你自己的问题写的更简洁:

      for (int z=0; z<4; ++z) {
          System.out.print(z);
      }
      

      上述代码的优点是变量zfor循环范围内,所以它不会意外与其他变量发生冲突。

      【讨论】:

        【解决方案5】:

        这是因为您使用后缀运算符分配 z 的值。

        http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

        int z = 0;
        i = z++; // i equals 0
        x = ++z; // x equals 2
        

        后缀运算符将在 i 赋值后增加 z 的值。

        一元运算符++将在x赋值之前增加z的值。

        将 z 之前的 ++ 视为赋值前的 +1,将 z 之后的 ++ 视为赋值后的 +1。

        【讨论】:

        • 我认为这是正确的答案,但您可能应该让读者了解它的含义,特别是 z++ 返回一个值,并且赋值使用该值。
        【解决方案6】:

        自增运算符已经递增z,您不必将返回值分配回z

        z++
        

        是后期增量。它返回 z 并在它增加 z 之后。 在您的第一个示例中,您基本上只是将 0 分配给 z 并且您的循环不应该结束。

        在您的第二个示例中,您将 z 的旧值分配给 x,然后递增 z。这意味着您不会像第一个示例中那样再次开始递增 0,但是当 z 达到 5(因此 z

        【讨论】:

          【解决方案7】:

          第一个最好写成

          int z=0;
          while(z++<4)
          {
             System.out.print(z);
          }
          

          int z=0;
          while(z<4)
          {
             z = ++z;
             System.out.print(z);
          }
          

          这里的预增量很重要,因为它会先递增然后赋值。而不是分配然后递增 - 除了在您的第一个示例中重置为 0 之外没有任何影响。

          因为当您执行z=z++ 时,它会将旧值重新分配回z,从而导致无限循环。

          第二个将结束,因为您没有重新分配回 z:

          int z=0;
          int x=0;
          
          while(z<5)
          {
              x=z++;
              System.out.print(x);
          }
          

          这将打印 1234。

          【讨论】:

            【解决方案8】:

            使用后自增运算符时,不需要将结果赋回变量。

            也就是说,你的代码应该是这样的:

            int z=0;
                while(z<4)
                {
                   ++z;
                   System.out.print(z);
            
                }
            

            在 Java 中,该操作在递增之前返回 z 的值(同时在幕后递增变量),然后将该值重新分配给 z。这就是为什么它永远不会改变。

            预增量运算符将执行增量并返回 NEW 结果,因此您将得到您期望的结果:

            int z=0;
                while(z<4)
                {
                   z=++z;
                   System.out.print(z);
            
                }
            

            这将打印1234

            【讨论】:

            • ...当然,正确的程序只会执行z++;++z; 而不是z=++z;,但很好地说明了差异。
            • 我认为它的最佳答案 tanx
            • @shanky:谢谢——如果你这么认为,请随意点击答案左侧投票区域下方的复选标记 :-)
            【解决方案9】:

            z=z++ 是程序员的错误——它所做的是将 z 递增,然后将 z 设置为其旧值——结果它用它的旧值覆盖了 z,从而撤消了递增。

            【讨论】:

            • 更准确地说,这只是一个逻辑错误。显然它会编译并运行得很好(尽管在提供的示例中,它会导致无限循环)。
            • 是的,我正在寻找正确的形容词来与单词 error 一起使用。 (“语义错误”或“程序员错误”)
            猜你喜欢
            • 2015-01-16
            • 2011-04-15
            • 1970-01-01
            • 2011-08-13
            • 2011-04-17
            • 2010-12-24
            • 2011-07-17
            • 2011-03-21
            • 1970-01-01
            相关资源
            最近更新 更多