欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

前置++和后置++ 運算的詳解及實例代碼

 更新時間:2016年09月18日 14:42:34   投稿:lqh  
這篇文章主要介紹了前置++和后置++ 的相關資料,并附示例代碼,幫助大家學習參考,需要的朋友可以參考下

一般認為前置++是先將變量的值加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,然后才繼續(xù)計算的。二者之間真正的區(qū)別是:前置++是將變量的值加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,再次循環(huán)同樣有temp=i,temp>100,這次是成立的,然后i+=1,直接跳出循環(huán),不會執(zhí)行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,再次循環(huán)
   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,接下來使用那個臨時變量參與運算。
三。從指令上說,后置++在執(zhí)行增值指令(iinc)前,先將變量的值壓入棧,執(zhí)行增值指令后,使用的是之前壓入棧的值。

希望通過此文,徹底理解前置++和后置++的運算區(qū)別,謝謝大家對本站的支持!

相關文章

  • 基于Spring?Cache實現Caffeine+Redis二級緩存

    基于Spring?Cache實現Caffeine+Redis二級緩存

    本文主要介紹了基于Spring?Cache實現Caffeine+Redis二級緩存,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • RocketMQ?offset確認機制示例詳解

    RocketMQ?offset確認機制示例詳解

    這篇文章主要為大家介紹了RocketMQ?offset確認機制示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Java中抽象類與方法的重寫方式

    Java中抽象類與方法的重寫方式

    這篇文章主要介紹了Java中抽象類與方法的重寫方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • MySQL主鍵約束和外鍵約束的實現

    MySQL主鍵約束和外鍵約束的實現

    在MySQL中,主鍵和外鍵約束是通過約束來實現的,本文主要介紹了MySQL主鍵約束和外鍵約束的實現, 具有一定的參考價值,感興趣的可以了解下
    2023-11-11
  • Java背包問題求解實例代碼

    Java背包問題求解實例代碼

    這篇文章主要介紹了Java背包問題求解實例代碼,其中涉及兩種背包:01和完全背包。分別講述了兩種背包的思路和實現方法,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • 使用Jitpack發(fā)布開源Java庫的詳細流程

    使用Jitpack發(fā)布開源Java庫的詳細流程

    這篇文章主要介紹了使用Jitpack發(fā)布開源Java庫的詳細流程,本文通過圖文實例代碼相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • @PathVariable獲取路徑中帶有 / 斜杠的解決方案

    @PathVariable獲取路徑中帶有 / 斜杠的解決方案

    這篇文章主要介紹了@PathVariable獲取路徑中帶有 / 斜杠的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java如何導出zip壓縮文件

    Java如何導出zip壓縮文件

    這篇文章主要介紹了Java如何導出zip壓縮文件問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 圖解JVM垃圾內存回收算法

    圖解JVM垃圾內存回收算法

    這篇文章主要介紹了圖解JVM垃圾內存回收算法,由于年輕代堆空間的垃圾回收會很頻繁,因此其垃圾回收算法會更加重視回收效率,下面小編就和大家來一起學習一下吧
    2019-06-06
  • jdk8使用stream實現兩個list集合合并成一個(對象屬性的合并)

    jdk8使用stream實現兩個list集合合并成一個(對象屬性的合并)

    本文主要介紹了jdk8使用stream實現兩個list集合合并成一個(對象屬性的合并),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論