目录
自增运算符:
例题一:
例题二:【阿里巴巴-笔试】
自增运算符:
不是原子操作;
前缀自增自减法(++a,--a): 先进行自增或者自减运算,再进行表达式运算;
后缀自增自减法(a++,a--): 先进行表达式运算,再进行自增或者自减运算;
int i = 0; i = i++;
0: iconst_0 | 把int型的0值压入操作数栈 |
1: istore_1 | 将一个数值从操作数栈上存储到局部变量表中 |
2: iload_1 | 将一个局部变量加载到操作数栈上 |
3: iinc 1by 1 | iinc是对int类型的值进行自增操作,后面第一个数值1表示,局部变量表的index值,说明要对此值执行iinc操作,第二个数值1表示要增加的数值。(这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0) |
6: istore_1 | 将一个数值从操作数栈上存储到局部变量表中 |
7: iload_1 | 将一个局部变量加载到操作数栈上 |
从执行顺序可以看到,这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。
x = -1;
y = x++ + ++x;
x 执行 x++ ,进行加运算的时候x = -1 (先运算,后自增),此时 x = 0,++x 结果是1(先自增,后运算),变大时变成-1 + 1,所以 y = 0;
例题一:
检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。
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++; }
}
正确答案: 0
单独看容易让人迷惑的int i = 0; i = i++;这句代码,使用jclasslib查看字节码;
0: iconst_0 | 把int型的0值压入操作数栈 |
1: istore_1 | 将一个数值从操作数栈上存储到局部变量表中 |
2: iload_1 | 将一个局部变量加载到操作数栈上 |
3: iinc 1by 1 | iinc是对int类型的值进行自增操作,后面第一个数值1表示,局部变量表的index值,说明要对此值执行iinc操作,第二个数值1表示要增加的数值。(这时局部变量表index为1的值因为执行了自增操作变为1了,但是操作数栈中栈顶的值仍然是0) |
6: istore_1 | 将一个数值从操作数栈上存储到局部变量表中 |
7: iload_1 | 将一个局部变量加载到操作数栈上 |
这里第1和第6执行了2次将0赋值给变量i的操作(=号赋值),i++操作是在这两次操作之间执行的,自增操作是对局部变量表中的值进行自增,而栈顶的值没有发生变化,这里需要注意的是保存这个初始值的地方是操作数栈而不是局部变量表,最后再将栈顶的值覆盖到局部变量表i所在的索引位置中去。
而fermin方法中的i因为不是引用变量,所以不会改变原有的i;最终答案是0
例题二:【阿里巴巴-笔试】
以下代码的输出结果是?【阿里巴巴-笔试】
public class Test{
static{int x=5;
}
static int x,y;
public static void main(String args[]){x--;myMethod( );System.out.println(x+y+ ++x);
}
public static void myMethod( ){y=x++ + ++x;}
}
prints:3
静态语句块中x为局部变量,不影响静态变量x的值
x和y为静态变量,默认初始值为0,属于当前类,其值得改变会影响整个类运行
y = x++ + ++x;
x 执行 x++ ,进行加运算的时候x = -1 (先运算,后自增),此时 x = 0,++x 结果是1(先自增,后运算),变大时变成-1 + 1,所以 y = 0,x = 1;
然后x+y+ ++x 等于3;