關於b=++b和b = b += 1的問題探討
阿新 • • 發佈:2019-01-08
問題一:byte b = 1; b = b += 1;
問題二:byte b = 1; b = ++b;
問題一和問題2中的結果在編譯時是沒有問題的,哪位朋友可以幫我解釋一下為什麼嗎?
byte b=1,這個我知道肯定是沒問題了,int型別的1自動轉化為了byte型別並賦值給了b,但是b + b+=1這個有點不太理解了,
b += 1是不是相當於b = b+1,如果是這樣的話,編譯應該有問題才對,b+1運算後的結果是int型別,需要強轉才能賦值給byte型別的。
第二個問題,b = ++b,先運算++再賦值,感覺也相當於b = b+1,為什麼這個編譯也不報錯呢
經過仔仔細細又看了兩遍老畢的“15-Java語言基礎(算術運算子_2&賦值運算子).avi”,已經有了答案了,如答案有不足之處,希望大家指出來: 一:byte b = 1; b = b += 1; 二:byte b = 1; b = ++b; 問題一: 對於第一個運算,首先,byte b = 1;實際上這個值是編譯器先進行了一次檢查,範圍在byte範圍內,則編譯通過, 同時將1這個int型別的值在底層轉化為了byte型別賦給了b; 再說說b = b += 1;這個運算是將b += 1的計算結果賦給了b,所以我們只說b += 1的運算過程就行了, b += 1,其實等價於 b = (byte)(b+1);底層會對這個結果進行強轉的,所以它編譯的時候沒事,如果b是127, 那麼加1後變成128了,成了int型別了,超過了byte型別的最大範圍了,怎麼辦?這時候底層會強轉,把int型別的 前面三個高位丟棄,丟棄後,如果剩下的一位中,最高位為1,則取反加一,就成了負數了,如果最高位為0,直接把 值賦給b 問題二、 b = ++b,這個運算的過程是,先進行++b的運算,再把運算後的結果賦給b,++b計算後是一個int型別的, 不管結果等於多少,底層會進行一個強轉,也就是說++b就相當於 b = (byte)(b+1),所以這個編譯也沒有問題,但是如果你 搞個byte b = 127; b = ++b;結果也會跟問題一一樣,大家可以測試一下
另外還有幾個類似的問題在此一起說明:
1. int count = 0; count = count + count++; System.out.println(count); 2. int count = 0; count = count++ + count; System.out.println(count); 3. int count = 0; for (int i = 0; i < 100; i++) { count = count + count++; } System.out.println(count); 4. int count = 1; for (int i = 0; i < 100; i++) { count = count + count++; } System.out.println(count); 複製程式碼 第一個問題: 要明白count = count + count++的結果,首先要知道兩個問題: 第一個是這個運算的運算順序,第二個是count++操作做了什麼事,對於運算順序,肯定是先運算等式右邊的 再賦值給左邊的變數,右邊的運算是從左到右算的,明白了這兩個問題再來看題就不復雜了. count = count + count++;先運算右邊,右邊從左到右算, 我們要是知道count++的結果就知道了右邊的結果了, count在跟左邊的count運算之前,會先進行一個複製,將原來的值複製一份,然後它本身的原值會自增, 需要注意的是原值的自增跟複製後的資料是沒有關係的,自增後,原值變成1了, 這時候進行count + count++進行運算,但是count++參與運算的是複製出來的那份值而不是自增後的結果, 由於等式右邊的左邊的count是在count++運算前就有值的,所以它是0,而count++的結果是0,所以 就是 0 + 0, 然後將結果賦給了等式左邊的count,結果列印就是0 第二個問題: 原理其實跟第一個問題差不多,但結果肯定是不一樣的,因為等式右邊的運算是要從左到右的,count++ + count, count先複製一份資料也就是0出來,然後進行自增這時候原值變為1了,而count++參與運算用的是複製出來的0參與 運算的,所以count++ + count實際上就是 0 + 1,為什麼這裡是0+1而不是0+0呢,因為count++運算雖然用的是複製出來 的那份資料,但是它本身的值已經自增到了1,而count++右邊的那個count拿的是自增後的原值也就是1, 所以這個列印結果是1 第三個問題: 如果你第一第二個問題已經看懂了,我相信第三個問題已經不言自明瞭,count = count + count++;列印的結果 其實就相當於count = count + count;雖然兩者底層運算有點差異,但結果是一樣的, 所以這個for迴圈不管有多少次 結果都是0 = 0 + 0,結果都列印為0 第四個問題: 原理也是一樣的因為count = count + count++的結果就相當於count = count + count; 所以再來看第四個問題的結果就不為怪了,但是第四個問題有些人可能會感到奇怪,因為結果是0,如果我們自己算也會感到奇怪, count首先等於1,for迴圈第一次1 = 1 + 1++結果為2(不解釋了吧),再運算的資料會越來越大為什麼會為0呢? 我也感到納悶,但我知道一旦這個count有一次結構為0,後面的所有for迴圈計算出的結果都為0了, 所以我們找到為0的時候for迴圈中的i等於多少, 經測算i為31的時候,結果為0,而i為30的時候count等於-2147483648,二進位制為 10000000000000000000000000000000,這時候count + count++, 就相當於count *2 了(兩個相同的資料相加相當於乘以2, 這個不用解釋吧),乘以2就相當於左移1位,結果為0,所以就出現了這樣的結果了