聊聊i++和++i

其实大家只要记住一句话就可以了,前++是先自加再使用而后++是先使用再自加!

前++和后++总结:其实大家只要记住一句话就可以了,前++是先自加再使用而后++是先使用再自加!

总结:
_x 负责中间变量保存i的值,最后一步都是_x赋值给等号左边的变量

++在前的时候,先自增,在保存值到_x,最后_x 的值赋值给等号右边的变量

++在后的时候,_x先保存值,在自增,然后把_x的值赋值给等号右边的变量

真实面试题与解析
看下面一段程序,相信每一个标准的程序员都做过:

package hello_java;

public class Test {
public static void main(String[] args) {
int i = 0;
i = i ++;
System.out.println(i);
}
}

这段代码的运行结果,估计多数人都背住了,但是底层究竟是怎么运行的,可能就。。。之前学习的时候,完全不认为这是一个问题,但是有一天当别人问我的时候,我竟发现自己只是记住了答案,隐约记得解释,但是就是说不出来,今天要pass掉这个问题。先看答案:

0

答案为什么是0?最底层的原因是 i = i++操作并不是原子性,而是分步进行的,如果你不能理解什么是原子性,可以先看这个操作

1 + 1 + 1 = ?

我想你大概率会直接得到答案3,但是对于一个小朋友来讲,他要先计算1 + 1 得到2之后再和1相加,得到最终的结果3 ,成年人虽然能够直接得到3这个答案,但是实际上我们中间是有一个2的,1 + 1 是原子性的,但是1 + 1 + 1 就不在是原子性的了。

对于i = i ++ 其实是存在一个中间变量比如 _x ,然后在将 _x 的值赋值给 i ,得到最后的结果:

_x = i ++ ; i 的值赋值给 _x ,然后 i 自增为 1 ,_x 为 0

i = _x ; i 的值被覆盖为 0

所以最终的结果是 0

= 的作用是将 = 右边的计算结果赋值给左边

最后,将下面的代码和上面的代码做一个比较:

package hello_java;

public class Test {
public static void main(String[] args) {
int i = 0;
int x ;
x = i ++;
System.out.println(x);//0
System.out.println(i);//1
}
}

public class Test {
public static void main(String[] args) {
int i = 0;
i = ++i;
System.out.println(i); //1
/*
i自增为1,_x 保存i的值,最后_x赋值给等号左边的变量
*/
}
}
注意: 一般而言赋值操作是原子性的,但是排除 long 和 double,为什么?因为他们俩都是64位的,在进行分配内存的时候,不会直接分配那么大的内存,所以分两次分内存,一次分配32 位。

大招:
最牛叉的是编译一下,看看class文件是怎么回事,到底是怎么走的:

i= i ++;

int i = 0;
byte var10000 = i;
int var2 = i + 1;
i = var10000;
System.out.println(i);

i = ++ i;

int i = 0;
int i = i + 1;
System.out.println(i);
这还不是最底层,编译之后,我们查看字节码文件,这需要汇编语言的基础,还好我大学的时候学习过汇编语言

总结:
_x 负责中间变量保存i的值,最后一步都是_x赋值给等号左边的变量

++在前的时候,先自增,在保存值到_x,最后_x 的值赋值给等号右边的变量

++在后的时候,_x先保存值,在自增,然后把_x的值赋值给等号右边的变量

你可能感兴趣的:(聊聊i++和++i)