Java 中的 i = i++ 問題

Java 中的 i = i++ 問題

 

int i = 0;
i = i++;
System.out.println(i);  // 0

問最後的輸出結果是什麼。我這兩天才開始看 Java,第一眼就認爲肯定是輸出 1 ,但如果結果真的這麼直觀就不會出成筆試題了。實際運行一下,結果居然是輸出 0。

如果把 i = i++ 換成 i = ++i 或者乾脆換成 i++。輸出結果就是 1 了。爲了完整性,把替換後的代碼也貼一下。

int i = 0;
i++;
System.out.println(i);  // 1
int i = 0;
i = ++i;
System.out.println(i);  // 1

解釋

這個問題其實想明白了就很簡單,只需要理解兩個關鍵的地方:1. 表達式的返回值。 2. 臨時變量。不信我們先來分析大家都知道的 i++++i 的區別。假設有下面一段 Java 代碼:

// e.g.1
int i = 0;
int j = 0;
int a = ++i;  // a=1, i=1
int b = j++;  // b=0, j=1

問最後 i j a b 的值各是什麼。相信很多人都能得到正確答案。所以我把答案直接註釋在代碼中了。很多人也能解釋個所以然來。但我們還是來分析一下:

a 的結果是表達式 ++i 的值,而 b 的結果是表達式 j++ 的值。大多數人都知道 ++i 返回的是 i 自增以後的值,而 j++ 返回的是 j 自增以前的值。a b 值不一樣,也就是表達式 ++i 和表達式 j++ 的返回值不一樣。

上面說這麼囉嗦就是爲了讓大家注意到表達式的返回值的概念。表達式都是有返回值的,不然就不能放在賦值操作符右邊了。而且無論多麼複雜的表達式都是在表達式計算完後才返回一個值(注意是計算完後)。表達式 ++i 的返回值就是 i 自增後的值,而表達式 j++ 的返回值是 j 自增前的值。

OK,我們終於引入了表達式的返回值這個概念。再思考一下, 表達式 ++i 直接在 i 自增完後返回 i 的值就行。那 j++ 要返回 j 自增前的值,怎麼做到?難道先返回 j 的值,然後再讓 j 自增嗎?不行,因爲表達式計算結束後才能返回一個值。編譯器普遍的做法是創建一個臨時變量來保存 j 自增前的值,在 j 自增完後再返回這個臨時變量的值。所以 b = j++ 底層發生的步驟如下:

step1: temp = j; // 創建一個臨時變量 temp 保存 j 的值,這個 temp 也是整個表達式的返回值
step2: 對 j 進行自增操作
step3: 將表達式的返回值 temp 賦值給 b
  • 1
  • 2
  • 3

然後臨時變量 temp 的使命就完成了。

注:可能有部分人誤以爲:表達式 j++ 是先返回 j 的值,然後再對 j 進行自增操作。這種理解是錯誤的。如果表達式都返回了,還計算個球。表達式只有在計算完後纔會進行返回。無論多麼複雜的表達式,返回值都在最後一步。

OK,到了這裏,原始問題就很清晰了。

int i = 0;
i = i++;
System.out.println(i);  // 0
  • 1
  • 2
  • 3

i = i++ 對應的步驟如下:

step1: 創建一個臨時變量 temp 保存 i 的值 // temp=i=0,temp 也是整個表達式的返回值
step2: 對 i 進行自增操作  // i 的值變成了 1
step3: 返回表達式的值,也就是將 temp 賦值 給 i  // i 的值變成了 temp 的值,所以 i 又變成了 0

--------------------- 作者:流沙的刺客 來源:CSDN 原文:https://blog.csdn.net/candcplusplus/article/details/54558333?utm_source=copy 版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章