检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。

题目

检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。

package algorithms.com.guan.javajicu; 
public class Inc { 
    public static void main(String[] args) { 
       Inc inc = new Inc(); 
       int i = 0; 
       inc.fermin(i); 
       i= i ++; 
       System.out.println(i);
    
    } 
    void fermin(int i){ 
       i++; 
    } 
}

A. 0
B. 1
C. 2
D. 3

答案

A

解析

运行这个程序,在c/c++和java会发现不一样,在c/c++中答案是1,在java中答案是0。

我们单独来看这两句代码:

int i = 0; 
i = i++;

使用javap进行反编译,我们得到了如下的JVM指令代码:

0: iconst_0
1: istore_1
2: iload_1
3: iinc          1, 1
6: istore_1
7: iload_1

逐条解释上面代码:
0:将int类型的0入栈;
1:将操作数栈顶的值0弹出,保存到局部变量表index=1的位置。
2:将局部变量表index 1位置的值的副本入栈。
3:iinc是对int类型的值进行自增操作,后面第一个1表示局部变量表的index值,即要进行操作的数值,第二个1表示要增加的数值。

这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0

6:将操作数栈顶的值弹出(值0),放到局部变量表index为1的位置。(覆盖了上一步的计算结果)
7:将局部变量表index 1位置的值的副本入栈。(这时局部变量表index为1的值是0,操作数栈顶的值也是0)

总结:从执行顺序可以看到,这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。

原创文章 81 获赞 90 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43332735/article/details/105532673