本文複製自https://blog.csdn.net/abnerwang2014/article/details/20656423,是爲了本身之後查看方便才複製過來的,謝謝原博主。git
爲了更好地解釋下面的代碼,先來介紹一些背景知識,在個人計算機中, char 類型佔 8 個比特位,那麼, unsigned char 類型能表示的數的範圍爲 0 ~ 2的8次方 - 1,即 0 ~ 255,共 256 個數;int 類型佔 32 個比特位,那麼 unsigned 類型所能表示的數的範圍爲 0 ~ 2的32次方 - 1,即 0 ~ 4294967295,共 4294967296 個數,接下來看下面的代碼:github
這是我寫在 Emacs 上的代碼,運行結果以下圖:
spa
下面對上圖的運行結果進行解釋:.net
unsigned char 類型能表示的數的範圍爲 0 ~ 255,可是咱們給屬於此類型的 c 和 j 賦值分別爲 -10 和 258,顯然超過了此類型所能表示的數的範圍,在此例中,有如下三種狀況:code
( 一 )、 當咱們所賦的值爲 負值 時,如以上代碼中變量 c 的情形,給它一個值 -10,最後將 c 的值賦給 d 後輸出,獲得 d = 246,即給 c 變量賦值 -10 後,它的值變爲 246,這是爲何呢?這是因爲當咱們給一個無符號類型賦一個 負值 時,其結果是咱們所賦的值與這個無符號類型能表示的數的總個數的和,即 d = -10 + 256,這樣一來結果固然是 246 了,顯然 246 是在此無符號類型所能表示的數的範圍內的(0 ~ 255),那麼,若是相加後假若仍然不在這個無符號類型所能表示的數的範圍內該怎麼辦呢?譬如如下的代碼:對象
運行後的結果以下:
blog
給 m 賦值爲 -258 ,最後 n = 254 ,即 m 的值變爲了254 ,這又是什麼狀況呢?按照以上分析的邏輯, -258 + 256 = -2, -2 仍然不在 unsigned char 所能表示的數的範圍內,這個時候怎麼辦呢?顯然,只須要將 -2 + 256,等於 254, 254 在 unsigned char 所能表示的數的範圍內,因此最後的結果爲 254,跟以上運行最後得出的結果相符合,故由以上分析,能夠得出如下結論:seo
當咱們給一個無符號類型賦一個超過其表示範圍的負值時,其最後的結果是該負值與該無符號類型所能表示的數的總個數的和,若是所得結果仍是一個不在此類型表示範圍的負數,則將所得結果重複以上相加的過程,直到最後獲得一個在其表示範圍的數,此即爲最後的結果ci
( 二 )、 讓咱們把目光轉回到第一個代碼片斷,將 unsigned char j 賦一個超出其表示範圍內的 正值 258 後,將 j 的值賦給 k,最後輸出 k = 2,即 j 的值變爲了 2 ,這又是爲何呢?實際上,當咱們賦給一個無符號類型一個超出它表示範圍的 正值時,結果是將咱們所賦的這個值對此無符號類型所能表示的數的總個數取模後的餘數,即 258 % 256 = 2,符合程序運行結果get
( 三 )、 觀察第一個代碼片斷中第 11 行以後的部分,一個有符號數 i 與一個無符號數 u 相加的情形,最後獲得 4294967264 這麼一個奇怪的數字,而不是像但願的同樣獲得 -32 ,這是爲何呢?這是由於這個表達式中無符號數大於有符號數,此種情形下,當把一個有符號類型和無符號類型相加時,須要先將有符號類型的數轉換爲無符號類型的數後再進行加法運算,(一)(二)中已經詳細說明了怎樣將一個有符號類型的數轉換爲一個無符號類型的數,對於這種狀況,-42 + 4294967296 = 4294967254 ,在 unsigned 的表示範圍內,即 -42 轉換爲無符號類型後爲 4294967254 ,而後再將此數值加上 i (即 10 ) ,得 4294967264 ,符合最後獲得的程序運行結果,關於這部份內容詳見個人博客 C++ 無符號類型的運算對象參與的類型轉換
最後咱們還須要另外強調的一點是,當咱們給帶符號類型賦予一個超過其表示範圍的值時,其結果是未定義的,程序可能繼續執行,可能崩潰,也可能生成垃圾數據
本文來自 abnerwang_smile 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/abnerwang2014/article/details/20656423?utm_source=copy