1. 程式人生 > >C語言中 char 型別的取值範圍為什麼是-128~127

C語言中 char 型別的取值範圍為什麼是-128~127

我們之前已經說過關於原碼、反碼和補碼的一些東西,如果你沒有看過,可以點這裡《 你知道原碼、反碼和補碼嗎,進來了解一下吧 》看一下 。

好了,可能你不會太想看,所以我們一起再來簡單的複習一下,如果我們現在有一個十進位制的整數 1 ,我們知道 1 個位元組等於 8 位,一個整型資料佔 4 個位元組,也就是說一個整型資料佔 4 個 8 位,也就是 32 位,所以整數 1 用二進位制表示,如下:

0000 0000 0000 0000 0000 0000 0000 0001

這串二進位制數我們就可以看成是整數 1 的原碼,那麼整數 1 的反碼和補碼是什麼呢,這裡我們只需要記住一句話即可,就是正數的原碼、反碼和補碼是相同的,所以整數 1 ,由於它是正數,所以它的原碼、反碼和補碼都是:

0000 0000 0000 0000 0000 0000 0000 0001

正數相對簡單,所以我們介紹到底為止,如果你不知道整數 1 的原碼為什麼是這串,你可以上網查一下關於十進位制轉二進位制的問題,這裡假設你們已經很清楚了,因為本文的重點不在討論進行的轉換問題上,或者你可以閱讀我之前的文章瞭解一下如何進行二進位制列印《 十進位制可以直接列印八進位制和十六進位制,那麼如何列印二進位制呢,對,右移 》 。

好了,接下來我們看一下負數的原碼、反碼和補碼,我們用 -1 來舉例,對於負數,我們的第一位數字開始有了作用,當第一位為 0 時表示是正數,當第一位為 1 時表示是負數,所以 -1 的原碼就是:

1000 0000 0000 0000 0000 0000 0000 0001

那麼反碼是什麼呢,反碼就是在原碼的基礎上符號位不變,其它位按位取反,所以反碼如下:

1111 1111 1111 1111 1111 1111 1111 1110

有了反碼,補碼就簡單了,就是在反碼的基礎上加上 1 ,計算過程如下:

1111 111111111111111111111111 111000000000000000000000000000000001
---------------------------------------
1111111111111111111111111111 1111

然後我們就得到了 -1 的補碼,如下:

1111 1111 1111 1111 1111 1111 1111 1111

怎樣驗證它對不對呢,你可以開啟 Xcode ,直接輸入如下程式碼執行看結果:

printf("%i\n"
, 0b11111111111111111111111111111111);

看看結果是不是 -1 。

好了,複習完畢,接下來回到今天的正題上,首先我們看一下無符號位的 char 型別,我們知道 char 型別只佔一位 。

所以如果是無符號 char 型別,那麼它的取值範圍就是:

00000000 ~ 11111111

即 0 ~ 255 。

如果是有符號的 char 型別,我們已經通過標題知道了它的取值範圍是 -128 ~ 127,因為有符號的 char 型別,則是分為正數和負數,所以,當然就存在兩個範圍段,0 ~ 127 和 -0 ~ -127,但是我們知道 -0 是說不通的,所以這時候這個 -0 要怎麼辦呢,那麼 -128又是怎麼出來的,考慮到一個不在了一個莫名多出來了,所以我們可以假設 -0 就是 -128 ,既然有了假設,接下來我們就來驗證到底是不是這樣 。

首先我們看一下 -128 的原碼是多少,如下:

0b1111 1111 1111 1111 1111 1111 1000 0000

你可以將其用 printf 進行列印,看一下結果是否為 -128 ,為了方便看,我們只看最後 9 位,第一位為符號位,是 1 ,後面就是 1000 0000 ,就是 -128 ,原碼為 1 1000 0000 ,反碼就為 1 0111 1111 ,補碼為 1 1000 0000 ,我們可以發現,原碼和補碼居然是一樣的,雖然 -128 是一個負數,但它的原碼和補碼居然一樣了,好了,由於 char 型別只佔 1 個位元組,也就是 8 位,所以我們要把最高位的 1 捨去了,這時候得到的八位二進位制數為 1000 0000 ,剛好就和 -0 的原碼相同,所以可以把 -0 直接看成是 -128 了,這是我的個人見解,歡迎批評指正 ,因為這確實是一個有意思的事情 。

如果你對Xcode感興趣,歡迎關注我的微信公眾號!