前置++和後置++ 運算的詳解及執行個體代碼_java

來源:互聯網
上載者:User

一般認為前置++是先將變數的值加1,然後使用加1後的值參與運算;而後置++是先使用該值參與運算,然後再將該值加1。

先看第一個例子:

package test;public class Plus_Test01 { public static void main(String[] args) {  int i = 100;  i = i++;  System.out.println(i); }}

猜猜結果是什嗎?

接著看第二個:

package test;public class Plus_Test02 { public static void main(String[] args) {  int k = 100;  while (true) {   if (k++ > 100) {    // System.out.println(k);    break;   }   System.out.println(k);  } }}

猜猜結果是什嗎?

實際上,不管是前置++,還是後置++,都是先將變數的值加1,然後才繼續計算的。二者之間真正的區別是:前置++是將變數的值加1後,使用增值後的變數進行運算的,而後置++是首先將變數賦值給一個臨時變數,接下來對變數的值加1,然後使用那個臨時變數進行運算。

對於如下程式碼片段(前置++):

int i=1;
int j=++i*5;

實際第二句上相當於:

i+=1; //將i加1
j=i*5; //將加1後的值與之進行計算, 此結果為:10

而對於如下程式碼片段(後置++):

int i=1;
int j=i++*5;

第二句上相當於:

int temp=i;  // 將i賦值給一個臨時變數
i+=1;        //將i加1
j=temp*5;   //將臨時變數與之計算, 此結果為:5

對於第一個例子,相當於:

int temp=i;
i+=1;
i=temp; //

所以結果應該為不變的,即100。

第一個例子的彙編代碼為:

 public static void main(java.lang.String[]);  descriptor: ([Ljava/lang/String;)V  flags: ACC_PUBLIC, ACC_STATIC  Code:  stack=2, locals=2, args_size=1   0: bipush  100   2: istore_1   3: iload_1   4: iinc   1, 1 //local var中第二個 加1   7: istore_1    //儲存至local var   8: getstatic  #16     // Field java/lang/System.out:Ljava/io/PrintStream;   11: iload_1 //載入的參數為棧中的第二個,即仍然為100   12: invokevirtual #22     // Method java/io/PrintStream.println:(I)V   15: return

對於第二個例子,其實不難,結果是101,注意看一下流程,以後不能在犯這樣的錯誤了。(流程為:首先比較temp=i,temp>100,,顯然不成立,將i+=1,跳到syso那一句,列印的當然是101,再次迴圈同樣有temp=i,temp>100,這次是成立的,然後i+=1,直接跳出迴圈,不會執行while裡面的語句)。

第二個例子的彙編(只選取了main方法):

 public static void main(java.lang.String[]);  descriptor: ([Ljava/lang/String;)V  flags: ACC_PUBLIC, ACC_STATIC  Code:  stack=2, locals=2, args_size=1   0: bipush  100  //100壓棧   2: istore_1     //儲存至第二個local var(第一個local var 是方法參數)   3: iload_1     //從第二個local var載入   4: iinc   1, 1  //給local var的2號位置的int值增加1(局部變數自增,結果仍然在local var中,運算元棧頂1不會變)   7: bipush  100 //100壓棧   9: if_icmple  15 //比較運算元棧頂的兩個int整型值,如果第一個小於或者等於第二個的話,然後跳轉到15行   12: goto   25 //否則跳轉到25行(即運算元棧頂1>運算元棧頂2)   15: getstatic  #2     // Field java/lang/System.out:Ljava/io/PrintStream;   18: iload_1 // //從第一個個local var載入   19: invokevirtual #3     // Method java/io/PrintStream.println:(I)V //調用該方法   22: goto   3 //再次回跳至3,再次迴圈   25: return //退出

第三個例子:

 package test;  public class Plus_Test03 {   static int proPlus() {   int i = 55;   int j = ++i;   return j; //56  }   static int postPlus() {   int i = 55;   int j = i++;   return j; //55  }   public static void main(String[] args) {  System.out.println(proPlus());//56   System.out.println(postPlus());//55   }}

第三個例子的彙編:

static int proPlus(); descriptor: ()I flags: ACC_STATIC Code:  stack=1, locals=2, args_size=0   0: bipush  55 //55壓棧   2: istore_0   //將int型棧頂的儲存至第一個local var   3: iinc   0, 1 //第一個local var加1   6: iload_0   //從local var載入   7: istore_1  //儲存至第二個local var   8: iload_1   //棧頂為第二個local var   9: ireturnstatic int postPlus(); descriptor: ()I flags: ACC_STATIC Code:  stack=1, locals=2, args_size=0   0: bipush  55    2: istore_0   3: iload_0    //載入至棧   4: iinc   0, 1 //第一個local var加1   7: istore_1   8: iload_1   9: ireturn

可見,前置++ 和後置++的不同點在於上面藍色(//第一個local var加1)的部分,這兩部分是反過來的。對於前置來說,會將local var中的數加1然後載入至棧中,而後置則是先從棧local var中載入至棧,然後將local var的加1,相當於留了一個備份。

結論:

一。前置、與後置++都是先將變數的值加1,而不是前置++先加1然後運算,而後置++先運算後加1。
二。從程式上說,後置++先將變數賦值給一個臨時變數,然後將變數的值加1,接下來使用那個臨時變數參與運算。
三。從指令上說,後置++在執行增值指令(iinc)前,先將變數的值壓入棧,執行增值指令後,使用的是之前壓入棧的值。

希望通過此文,徹底理解前置++和後置++的運算區別,謝謝大家對本站的支援!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.