1. 程式人生 > >深入理解i++和++i的區別

深入理解i++和++i的區別

首先:

  • i++ : 先取i的值作為表示式的值,然後執行 i = i + 1
  • ++i : 先執行 i = i + 1,再取運算完之後的值作為表示式的值

舉例和解釋:

先來個熱身的簡單例子

    public static void main(String[] args) {
		int i = 0;
		System.out.println("i++的值為:" + i++);
		i = 0;
		System.out.println("++i的值為:" + ++i);
	}

輸出:(有圖有真相)

 

可以看到表示式的值為先前說的那樣,可以總結為:

  • 加號在前,先加再取值
  • 加號在後,先取值再加

接下來舉一個常見的面試題例子:

	public static void main(String[] args) {
		int i = 0;
		i = i ++;
		System.out.println("i的值為:" + i);
	}

結果:

可以看到 i = i ++;的結果為0。

看到這裡可能有的小夥伴會奇怪,i = i ++ 為什麼結果為0而不是1,這不是先讓 i = 0,然後讓 i自增麼,怎麼就不對了呢?

其實前面說的沒有問題,這裡有兩個運算子 第一個是賦值運算子 ' = ' , 第二個是 自增運算子 ' ++ ' , 我們知道賦值運算子的順序為先計算表示式右邊,再把表示式的值賦值給左邊,真正的運算順序是先計算 i ++,在計算 賦值給i,而從上一個例子我們可以知道表示式 i ++ 的值為 0,此時,=右邊表示式的值為0,接下來是i 的自增操作,這個操作完畢後 i 的值確實為1,但還有下一步:把表示式的值賦值給 i ,表示式的值為0,於是 i 的值又變為了 0 ,最後輸出 i 的值為 0。

下面我們來看這段程式碼的底層是怎麼實現的(這部分適合對java有一定了解的童鞋看):

(為了簡單,把輸出部分的程式碼取掉了已經)

下面我來新增點註釋

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0              //第一步先把常量 0 放入棧頂
       1: istore_1              //從棧頂取出值(0)賦值給變數1( 前兩行對應 int i = 0;)
       2: iload_1             //把變數1的值取出放入棧頂(這一步是取 i++ 的值作為整個表示式的值)
       3: iinc          1, 1      //讓變數1的值加1        (這一步對應 ++ 自增運算子)
       6: istore_1                //把棧頂的值取出,賦值給變數1  ( 對應 = 賦值運算子)
       7: return                    //main方法結束

程式碼前兩行(標號為 0,1的行)是對應的   int  i = 0; 

(int i = 0;其實是int i; 然後 i = 0;其中變數宣告的部分是儲存在區域性變量表中,方法位元組碼中沒有 int i; 宣告的部分)

即把常數0賦值給 i, (這裡i 就是 變數 1),i = 0;也分兩步其實,第一步先把0放入棧頂,然後從棧頂取出值放入變數1

標號為 2 3 6 的行對應  i = i ++;(不要問第4行第5行去哪裡了,我們知道 i ++ 並不是一個原子操作,而是先取 i 的值,然後 讓這個值+1, 然後把這個值寫回 i ,關於原子操作不懂的同學百度一下~。這裡java的位元組碼為後兩行空出來了)。

2:先計算 = 右邊  i++ 的值,發現該值為 i ,就把 i 的值(此時為0)放入棧頂

3:計算 i ++的值,現在 i 的值為1(這裡還可以展開,想繼續深入瞭解的同學到這:深入理解i++為什麼不是原子操作

6:標號為2的程式碼已經計算出 = 賦值運算子右邊的值了,直接把棧頂的值寫會 = 左邊的 i 

7:程式碼結束,return

因此 i = i ++ 操作相當於沒有執行任何操作。

 

歡迎點評和指正,點選這裡檢視博主的其他部落格