深入理解i++和++i的区别

首先:

  • i++ : 先取i的值作为表达式的值,然后执行 i = i + 1
  • ++i : 先执行 i = i + 1,再取运算完之后的值作为表达式的值

举例和解释:

先来个热身的简单例子

    public static void main(String[] args) {
		int i = 0;
		System.out.println("i++的值为:" + i++);
		i = 0;
		System.out.println("++i的值为:" + ++i);
	}

输出:(有图有真相)

可以看到表达式的值为先前说的那样,可以总结为:

  • 加号在前,先加再取值
  • 加号在后,先取值再加

接下来举一个常见的面试题例子:

	public static void main(String[] args) {
		int i = 0;
		i = i ++;
		System.out.println("i的值为:" + i);
	}

结果:

可以看到 i = i ++;的结果为0。

看到这里可能有的小伙伴会奇怪,i = i ++ 为什么结果为0而不是1,这不是先让 i = 0,然后让 i自增么,怎么就不对了呢?

其实前面说的没有问题,这里有两个运算符 第一个是赋值运算符 ' = ' , 第二个是 自增运算符 ' ++ ' , 我们知道赋值运算符的顺序为先计算表达式右边,再把表达式的值赋值给左边,真正的运算顺序是先计算 i ++,在计算 赋值给i,而从上一个例子我们可以知道表达式 i ++ 的值为 0,此时,=右边表达式的值为0,接下来是i 的自增操作,这个操作完毕后 i 的值确实为1,但还有下一步:把表达式的值赋值给 i ,表达式的值为0,于是 i 的值又变为了 0 ,最后输出 i 的值为 0。

下面我们来看这段代码的底层是怎么实现的(这部分适合对java有一定了解的童鞋看):

(为了简单,把输出部分的代码取掉了已经)

下面我来添加点注释

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0              //第一步先把常量 0 放入栈顶
       1: istore_1              //从栈顶取出值(0)赋值给变量1( 前两行对应 int i = 0;)
       2: iload_1             //把变量1的值取出放入栈顶(这一步是取 i++ 的值作为整个表达式的值)
       3: iinc          1, 1      //让变量1的值加1        (这一步对应 ++ 自增运算符)
       6: istore_1                //把栈顶的值取出,赋值给变量1  ( 对应 = 赋值运算符)
       7: return                    //main方法结束

代码前两行(标号为 0,1的行)是对应的   int  i = 0; 

(int i = 0;其实是int i; 然后 i = 0;其中变量声明的部分是储存在局部变量表中,方法字节码中没有 int i; 声明的部分)

即把常数0赋值给 i, (这里i 就是 变量 1),i = 0;也分两步其实,第一步先把0放入栈顶,然后从栈顶取出值放入变量1

标号为 2 3 6 的行对应  i = i ++;(不要问第4行第5行去哪里了,我们知道 i ++ 并不是一个原子操作,而是先取 i 的值,然后 让这个值+1, 然后把这个值写回 i ,关于原子操作不懂的同学百度一下~。这里java的字节码为后两行空出来了)。

2:先计算 = 右边  i++ 的值,发现该值为 i ,就把 i 的值(此时为0)放入栈顶

3:计算 i ++的值,现在 i 的值为1(这里还可以展开,想继续深入了解的同学到这:深入理解i++为什么不是原子操作

6:标号为2的代码已经计算出 = 赋值运算符右边的值了,直接把栈顶的值写会 = 左边的 i 

7:代码结束,return

因此 i = i ++ 操作相当于没有执行任何操作。

欢迎点评和指正,点击这里查看博主的其他博客

猜你喜欢

转载自blog.csdn.net/qq_35425070/article/details/83865654