关于i++和++i

198 阅读2分钟

思考i++++i的相同点与不同点

1. i++++i的相同点

1.1 都有返回值

i++++i的本质都是函数调用,他们都有返回值。

2. i++++i的不同点

2.1 i++的返回值和++i的返回值

i++的返回值

如果赋值了,i++会先把计算结果放在临时变量,临时变量再赋值。 i++的返回值是自加前i的值(可以认为是先使用再加加),可以认为是一个独立的常量。

@Test
public void test2(){
    int i = 10;
    i = i++;
    
    System.out.println(i);//返回10
}

因为i++的返回值是自加前i的值,因此i等于10。通过jclasslib查看字节码。

 0 bipush 10
 2 istore_1
 3 iload_1
 4 iinc 1 by 1
 7 istore_1
 8 getstatic #7 <java/lang/System.out>
11 iload_1
12 invokevirtual #13 <java/io/PrintStream.println>
15 return
  • bipush

push主要是放在栈空间的操作数栈中

bipush 10,将10存放在操作数栈中

  • istore

istore_1,把局部变量10取出来,存放在栈空间的局部变量表角标为1的位置上

  • iload

iload_1,把栈空间的局部变量角标为1的值再放在操作数栈中

  • iinc

iinc 1(索引) by 1(增长),iinc在局部变量表上索引 1 增长 1。局部变量表中索引1的位置为11。

  • getstatic

getstatic #7 <java/lang/System.out>,输出

@Test
public void test3(){
    int i = 2;
    i *= i++;
    System.out.println(i);//返回4
}

因为i++的返回值是自加前i的值,因此i++等于2,i = i * (i++)为4。

@Test
public void test6(){
    int i = 1;
    i = i++ + i++;
    System.out.println(i);
}

前一个i++返回值1,此时i为2,后一个i++返回值2,因此1 + 2打印结果为3。

++i的返回值

在C++中++i的返回值不是一个具体的数,是变量i的引用/指针,做运算的时候才能确定。Java中的++i 先将变量的值加1,然后再使用变量的新值。 在没有赋值的情况下,两个语句的汇编是相同的。

@Test
public void test4(){
    int i = 10;
    i = i + (i++) + (++i);
    System.out.println(i);//返回32
}

从左到右依次运算,10 + 10(此时i为11)+ (11+1),因此结果为32。

@Test
public void test7(){
    int i = 1;
    i = i++ + ++i;
    System.out.println(i);
}

i++的返回值1,此时i为2,++i返回值3,因此1 + 3返回值为4。

@Test
public void test8(){
    int i = 1;
    i = ++i + ++i;
    System.out.println(i);
}

前一个++i的返回值为2,此时i为2,后一个++i的返回值为3,因此2 + 3返回值为5。