【问题标题】:Java increment and assignment operator [duplicate]Java增量和赋值运算符[重复]
【发布时间】:2014-08-25 05:18:03
【问题描述】:

我对 post ++ 和 pre ++ 运算符感到困惑,例如在以下代码中

int x = 10;
x = x++;

sysout(x);

会打印 10 吗?

它打印 10,但我希望它应该打印 11

但是当我这样做时

x = ++x; instead of x = x++;

它会像我预期的那样打印 11,那么为什么 x = x++;不会改变 x 的值?

【问题讨论】:

  • 由于这种混乱,你真的不应该在实际代码中这样做。
  • 而不是x = x++ ==> x++
  • 投票重新开放:重复的问题是关于前增量和后增量之间的特定差异。虽然理解这种差异有助于回答这个问题,但它并不是完全重复的。

标签: java increment post-increment pre-increment


【解决方案1】:

在准备 Java 认证考试时,我还发现后增量运算符的复杂性。大多数,即使是有经验的,认为后增量 (++) 运算符会在执行 statement 后递增变量,就像上面提到的@bartektartanus 一样。这种想法对于大多数现实世界的编码来说已经足够好了,但是如果一个后/前递增/递减变量在一个语句中出现不止一次,那么这种想法就会失效。看起来所谓的面试/知识测试问题会及时检查这个松散的假设。值得打破这一点。上面接受的答案对于简洁的逻辑助记符没有太大帮助。

public class Test {
    static int x = 10;

    public static void main(String[] args) {
        print(x++);
    }

    private static void print(int x) {
        System.out.println(x);
        System.out.println(Test.x);
    }
}

Output
10
11

根据常见假设,静态变量 x 将在完成对 print 方法的调用后递增。但是当在方法内部检查时,它已经增加了。因此,后递增、递减运算符将变量值提交给作为参数的方法或运算符,并在运算符/方法执行之前立即递增/递减相关变量。预递增/递减操作有点不那么令人困惑,但即使这种情况发生在每个方法或运算符,而不是整个语句。

// The OP
int x = 10;
x = x++; // x = 10. x does get incremented but before the assignment operation

int x = 10;
x = x++ + x; // x = 21. x got incremented immediately after the addition operator grabbed its value.

【讨论】:

    【解决方案2】:

    当你这样做时:

    x = x++;
    

    它实际上被翻译为“将'x'分配给'x'然后将'x'加一”。

    而在这种情况下:

    x = ++x;
    

    它被翻译为“将'x'加一,然后将其分配给'x'”。

    【讨论】:

    • 好像是这样,去掉了先例。
    【解决方案3】:

    Post Increment(n++) : 先执行语句,然后将值加一。

    Pre Increment (++n) : 先将值加一然后执行语句。

    例子:

    class IncrementTest{
        public static void main(String[] args){
    
            System.out.println("***Post increment test***");
            int n = 10;
            System.out.println(n);      // output  10
            System.out.println(n++);    // output  10
            System.out.println(n);      // output  11
    
            System.out.println("***Pre increment test***");
            int m = 10;
            System.out.println(m);      // output  10
            System.out.println(++m);    // output  11
            System.out.println(m);      // output  11
        }
    }
    

    【讨论】:

      【解决方案4】:

      引用The Java tutorials - Assignment, Arithmetic, and Unary Operators:

      递增/递减运算符可以在操作数之前(前缀)或之后(后缀)应用。代码result++;++result; 都会以结果加一结束。唯一的区别是前缀版本 (++result) 评估为递增值,而后缀版本 (result++) 评估为原始值。如果您只是执行简单的递增/递减,那么您选择哪个版本并不重要。但是,如果您在较大表达式的一部分中使用此运算符,您选择的那个可能会产生显着差异。

      【讨论】:

        【解决方案5】:

        我没有在 JLS 中找到参考,所以这个答案是基于推测您没有调用未定义的行为,因为这是 Java。

        x = x++; // Assign the old value of `x` to x, before increment.
        x = ++x; // Assign the new value of `x` to x, after increment.
        

        这是基于后缀和前缀运算符的定义。

        【讨论】:

          【解决方案6】:

          不,10 的打印输出是正确的。理解结果背后原因的关键是前增量++x 和后增量x++ 复合赋值之间的区别。当您使用预增量时,表达式的值是在执行增量后获取的。但是,当您使用后增量时,表达式的值会在增量之前获取,并在增量结果写回变量后存储以备后用。

          这是导致您所看到的事件的顺序:

          • x 分配给 10
          • 由于++在后增量位置,x的当前值(即10)被存储起来供以后使用
          • 11 的新值存储到 x
          • 10 的临时值存储回x,直接覆盖已存储在那里的11

          【讨论】:

            猜你喜欢
            • 2011-11-16
            • 1970-01-01
            • 2018-05-13
            • 1970-01-01
            • 2016-05-10
            • 2015-03-19
            • 2017-11-21
            • 1970-01-01
            相关资源
            最近更新 更多