天天看點

【C語言】整型在記憶體中的存儲

整型在記憶體中的存儲

char

short

int

long

以上都分為有符号(signed)與無符号(unsigned)的類型

計算機在表示一個數字時,是采用二進制的方式,是以為了準确表示一個數的正負,每一個有符号數都将其最高位視作是符号位,最高位為0表示正數,最高位為1表示負數。我們接下來以有符号整型int的數字進行分析。

一個有符号整數由符号位+數值位組成,數值位是其最高位,分别以0/1表示正/負

對于正數來說,反碼補碼都與原碼相同;

對于負數來說,符合以下3條規則:

原碼:将十進制數字直接翻譯為二進制數

反碼:原碼的符号位不變,其他位按位取反

補碼:反碼+1

而對于整型來說,整型在記憶體中實際上是以補碼的形式進行存儲的。

有的同學可能就會問了,為什麼計算機要發展出原碼、反碼、補碼這麼多種碼呢?

這就與計算機對于整數的運算有關了。

cpu隻有加法器,減法在運算時也會被視作一個數加另一個負數。考慮到整數的最高位是符号位,兩個整數中若包含負數,以原碼直接相加得到的數一定是不對的。是以問題就變成了如何使得運算簡單而精确,既要處理符号位,又要隻進行加法運算,達到以某一種二進制形式的“碼”直接相加就能得到正确結果。

下面,我們以60+(-18)為例,分别用原碼、反碼、補碼直接進行二進制的運算。

顯然,得到了的原碼轉化為10進制是-78,并非正确答案42。

顯然,得到了的反碼轉化為10進制原碼是41,并非正确答案42,但是隻與正确答案相差(+1),于是,我們就想将負數的反碼+1,即變成“補碼”來進行運算,而又正數的補碼是原碼本身,這時候我們看看會怎麼樣呢?

顯然,得到了的補碼轉化為10進制原碼是42,我們得到了正确結果。

綜上,我們發現,隻要将兩個整數使用補碼進行運算,就不需要考慮它們的符号位了,将它們的所有位直接簡單相加即可,就能得到正确的結果。

對于char類型整數,-1用二進制補碼表示為

當我們已知一個負數的二進制補碼時,用比這個數多一位的、最高位為1、其他位全0、這裡應為9位的二進制數

直接減去-1的二進制補碼得

得到的數就是十進制(-1)的絕對值,也就是1,隻要加上負号,就能快速得到這個負數二進制補碼的十進制原碼。

原理十分簡單,一個負數的原碼加上補碼 =原碼+反碼+1 = 所有二進制位全1再加1 = 多一位的、最高位為1、其他位全0

在記憶體中,資料的大小端存儲是在位元組尺度上進行讨論的

大端存儲模式:資料的低位儲存在記憶體的高位址,資料的高位儲存在記憶體的低位址

小端存儲模式:資料的低位儲存在記憶體的低位址,資料的高位儲存在記憶體的高位址

在計算機系統中,我們通常是以位元組為機關存儲資料的,每個位址對應一個位元組。

一個位元組為8bit,但是在c語言中除了8bit的char之外,還有16bit的short,32bit的int。另外,對于位數大于8位的處理器,例如16位和32位的處理器,由于寄存器寬度大于一個位元組,那麼必然存在着如何将多個位元組安排的問題。這邊導緻了大小端存儲模式的誕生。

我們以int類型的數0x01ff4218為例(兩個十六進制位即為1個位元組),看一下在大小端下這4個位元組分别是如何配置設定的

大端存儲模式

【C語言】整型在記憶體中的存儲

小端存儲模式

【C語言】整型在記憶體中的存儲

算法簡單概括:截取4個位元組大小的int整型的1個位元組的低位。若機器為大端位元組序,該位元組存儲0x00;若機器為小端位元組序,該位元組存儲0x01;

c primer plus, 第六版, p494

繼續閱讀