Java篇—自增(自減)陷阱的分析總結

講述自增(自減)陷阱問題之前,先給大家回顧一下前置++和後置++的區別:

public class Test {
    public static void main(String[] args) {
        System.out.println("i++");
        int i = 3;
        int count = (i++) + (i++) + (i++);
        //i=6
        System.out.println(i);
        //count=3+4+5=12
        System.out.println(count);


        System.out.println("++i");
        int j = 3;
        count = (++j) + (++j) + (++j);
        //j=6
        System.out.println(j);
        //count=4+5+6=15
        System.out.println(count);
    }
}

區別總結如下:

前置++(++i):先給值自增1,然後再參與運算(先賦值再使用);

後置++(i++):先參與運算,然後再給值自增1(先使用再賦值)。

注:前置--(--i)和後置--(i--)的區別同上。

       重點來了,請集中注意力,筆者在刷題時,遇到一個很靈異的事件,話不多說,上代碼,如下所示:

public class TestDemo {
    public static void main(String[] args) {
        int count = 0;
        for (int i = 0; i < 10; i++) {
            count = count++;
        }
        System.out.println("count的值爲:" + count);
    }
}

最後輸出的count值是多少? 我相信很多人都直接會說count爲10嘛,這有什麼難的!結果是多少,編譯器告訴你!!!

驚訝嗎?count的值沒變,還是最初始的值0,並不是我們認爲的10。

福利來了,筆者下去查閱了很多資料,瞭解到Java的JVM對自增是這樣處理的:首先把count 的值(注意是值,不是引用)拷貝到一個臨時變量區,然後對 count變量加1,最後返回臨時變量區的值。

程序第一次循環時的詳細處理步驟如下:

step1:JVM把count值(其值是0)拷貝到臨時變量區;

step2:count值加1,這時候count的值是1;

step3:返回臨時變量區的值,注意這個值是0,沒修改過;

step4:返回值賦值給count,此時count值被重置成0。

注:於是第一次循環後count的值還是0,其他9次的循環也是一樣的,最終你會發現count的值始終沒有改變,仍然保持着最初的狀態。

簡而言之,可以將自增理解爲如下代碼:

public int autoIncrement(int count){  
    //先保存初始值  
    int temp =count;  
    //做自增操作  
    count = count+1;  
    //返回原始值  
    return temp;  
} 

那麼,“count = count++”這條語句的代碼含義則可以理解爲:

temp = count;
count = count + 1;
count = temp;

如果將語句改爲,“count = ++count”呢?修改對應代碼後:

public class TestDemo {
    public static void main(String[] args) {
        int count = 0;
        for (int i = 0; i < 10; i++) {
            count = ++count;
        }
        System.out.println("count的值爲:" + count);
    }
}

運行結果如下:

“count = ++count”這條語句的代碼含義則可以理解爲:

//前置++嘛,先賦值再使用咯
temp = count + 1;
count = count + 1;
count = temp;

細心閱讀此題,不難發現,此代碼只是想給count自增10次,那麼如果我們將語句“count = count++”改爲“count++”,結果毋庸置疑,count的值肯定爲10,雖然語句“count = ++count”等效於“count++”,但筆者仍然推薦大家使用語句“count++”,原因很簡單,語句“count = ++count”不容易理解。

筆者查閱資料得知,C++中“count=count++”與“count++”是等效的,而在PHP中則保持着與Java相同的處理方式。

關於此類陷阱問題,代碼總結如下:

public class AutoIncrementAndAutoDecrement {
    public static void main(String[] args) {
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        int count4 = 0;
        for (int i = 0; i < 10; i++) {
            count1 = count1++;
            count2 = ++count2;
            count3++;
            ++count4;
        }
        System.out.println("表達式:count1 = count1++ ,循環結束後,count1的值爲:" + count1);
        System.out.println("表達式:count2 = ++count2 ,循環結束後,count2的值爲:" + count2);
        System.out.println("表達式:count3++ ,循環結束後,count3的值爲:" + count3);
        System.out.println("表達式:++count4 ,循環結束後,count4的值爲:" + count4);
        System.out.println();
        int num1 = 10;
        int num2 = 10;
        int num3 = 10;
        int num4 = 10;
        for (int j = 0; j < 10; j++) {
            num1 = num1--;
            num2 = --num2;
            num3--;
            --num4;
        }
        System.out.println("表達式:num1 = num1--,循環結束後,num1的值爲:" + num1);
        System.out.println("表達式:num2 = --num2,循環結束後,num2的值爲:" + num2);
        System.out.println("表達式:num3--,循環結束後,num3的值爲:" + num3);
        System.out.println("表達式:--num4,循環結束後,num4的值爲:" + num4);
    }
}

輸出結果如下:

心得總結:

(1)自增自減操作時,直接使用count++(++count)或者count--(--count)即可;

(2)循環語句中對變量的前置++(--)和後置++(--)的輸出結果是相同的。

注:如果變量的修改涉及到表達式,那麼就要特別注意前置++(--)和後置++(--)的區別了。

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