今天,我看到了三个关于i++和++i的编程题,对其进行研究后整理了以下的内容:
第一题:
int a = 0;
for (int i = 0; i < 99; i++) {
a = a ++;
}
System.out.println("a: " + a);
相信大家只要对于i++的运作原理有所了解,知道是先赋值后自增的运作顺序的话应该很容易解出这道题。
答案如下:
第一题:
a: 0
如果从jvm虚拟机的角度可以这样理解:
如下图运行结果:
我们运行代码后打开idea工具栏找到view下的Show Bytecode工具,如下:
点击后会弹出一个字节码文件,如下:
我们只用关注L5这一行,这一行才是i++运行的核心:
L5
LINENUMBER 24 L5
ILOAD 1
IINC 1 1
ISTORE 1
这里面最重要的只有最后三行,首先是"ILOAD 1",这条指令的意思是将变量a的index为1的值压入操作数栈的栈顶,如下图:
"IINC 1 1"这条指令意为将index为1的局部变量+1,即下图:
"ISTORE 1"意为将当前栈顶的参数赋给index为1的局部变量,如下图:
因此L5这一行的指令运行完毕后a还是为0,所以循环无论运行了多少次,a = a ++的运行结果始终为a = 0。
第二题:
System.out.println("第二题: ");
int a = 0;
for (int i = 0; i < 99; i++) {
a = ++ a;
}
System.out.println("a: " + a);
与上一题不同,++i的运行原理为先自增,再赋值,因此最终结果完全不同,本题答案如下:
第二题:
a: 99
我们运行后打开Show Bytecode工具,看一下这道题的字节码:
我们依旧关注L5这一行:
L5
LINENUMBER 31 L5
IINC 1 1
ILOAD 1
ISTORE 1
"IINC 1 1"这一句指令意为index为1的局部变量+1:如下图:
"ILOAD 1"这一句指令意为将index为1的局部变量压入操作数栈的栈顶,如下图:
"ISTORE 1"这一句指令意为将当前栈顶的参数赋给index为1的局部变量,如下图:
可以看到a的值在此时已经变成1了,由此类推,当i = 98的时候,可以得出结果a = 99。
第三题:
问题如下:
System.out.println("第三题: ");
int a = 0;
int b = 0;
for (int i = 0; i < 99; i++) {
a = a ++;
b = a ++;
}
System.out.println("a: " + a);
System.out.println("b: " + b);
答案如下:
第三题:
a: 99
b: 98
运行程序后打开Show Bytecode工具,可以看到如下字节码:
这次我们要关注三行,分别是L6、L7、L8:
L6
LINENUMBER 39 L6
ILOAD 1
IINC 1 1
ISTORE 1
L7
LINENUMBER 40 L7
ILOAD 1
IINC 1 1
ISTORE 2
L8
LINENUMBER 38 L8
IINC 3 1
GOTO L4
操作流程如下:
可以看到当i = 0时,a 已经为1,b此时为0,i = 2时,a将为2,b在此时为1,以此类推,i = 98时,a = 99,b=98。由于篇幅所限,所以没有将流程全部写出来,感兴趣的朋友可以自己计算一遍。
由于本人初次接触字节码,有所错漏之处,敬请指正。