不一樣平臺下int類型、指針類型的數據大小

不一樣平臺下int類型、指針類型的數據大小

對於int類型數據和指針類型數據的大小,是很是基礎的問題。express

在一個具體的平臺上,肯定他們最好的辦法就是使用sizeof(type)對其進行判斷,返回當前數據類型的大小。編程

在不一樣的平臺下,int類型和指針類型的數據類型大小時怎樣的呢?若是要給出一個統一的答案,天然不可能集齊每一個平臺,一個個地去試,咱們必須從底層進行分析。優化

數據總線和地址總線

計算機內的數據總線是CPU與外設進行數據交換的通路,而地址總線則是CPU用於尋址的通路。ui

數據總線的位數決定了CPU與外設一次能夠傳輸的字節數。翻譯

而地址總線則決定了CPU能夠尋址的範圍,若是是32位地址線,每根地址線傳輸一位,可表示的範圍爲0~2^32-1,因爲內存中的基本單位是byte,因此也就對應0~2^32-1 byte,也就是0~4GB,對應於內存的可取範圍。設計

總線的位數通常也用總線寬度來表示。指針


一個常見的誤區是:地址總線和數據總線的寬度老是保持一致的。code

這個錯誤想法的原因就是沒有弄清楚地址總線和數據總線的工做原理,咱們能夠這樣理解:教程

在一個很大的倉庫中,地址總線表明一張倉庫地圖的座標,而數據總線則是取貨的推車,地圖座標系的大小(也就是地址總線的寬度)決定了它能夠記錄多大的倉庫面積,而推車的大小(即數據總線的寬度)決定了一次能夠取多少貨。內存

倉庫管理員根據地圖找到貨物存放的地址,而後使用推車來存取貨物。

在這個模型中,倉庫的面積能夠很是大,只須要將地圖座標繪得足夠大,而取貨的推車能夠很小,只是取大件貨物的時候多跑幾回。

一樣的,管理員能夠買個足夠大的推車,而倉庫面積並不大,只是一般在取貨的時候,推車不能被裝滿,存在一些空間浪費問題。


因此說,地址總線和數據總線在寬度上沒有太大的聯繫,可是,芯片設計者爲了平衡時間效率和空間效率,同時考慮到硬件上的影響,一般使用一樣的地址總線寬度和數據總線寬度。

舉一個數據總線和地址總線寬度不一樣的例子:在經典的8086計算機中,數據總線爲16位,地址總線則是20位。

芯片的位數

一般,咱們所說的一個芯片是多少位的,究竟是看它的數據總線寬度仍是地址總線寬度呢?

答案是:決定一個芯片多少位,是由這個芯片一次能處理多少位數據決定的,等於片內寄存器的寬度,同時能夠當作是數據總線的寬度。

爲何這裏說的是芯片位數能夠當作是數據總線的寬度而不是等於數據總線的寬度呢?按照目前的狀況而言,幾乎全部的芯片位數都等於數據總線寬度。

可是從嚴格意義上來講,數據總線是用來傳輸數據的,芯片位數指的是處理數據的寬度,數據的傳輸和處理並不是同一個概念,傳輸和處理數據的寬度是能夠不同的,只是實際狀況下數據傳輸的寬度和處理的寬度是同樣的,固然,這種區分有點吹毛求疵,因此,芯片位數等於數據總線寬度也是一種可接受的答案(固然,過去都是一致不表明將來也是一致,概念仍是要分清)。

同時,在編程時,咱們一般碰到一個叫作"字長"的概念,字長一般等於數據總線的寬度。

int型數據的大小

常見的第二個誤區是:int型數據的大小,也就是sizeof(int)的大小徹底跟隨硬件平臺的位數。

這個誤區的產生是源於咱們初學C語言時的教程:在16位芯片上int型類型大小爲16位,即兩字節,而在32位機器上,int型爲32位,即四字節。 以此類推,由此咱們就創建的一個模糊且錯誤的概念:int型數據的大小是跟隨於平臺的位數。

事實上,正確的答案是:int型數據的大小和硬件平臺位數無關,它是由C語言標準和編譯器共同決定的。

爲此,博主查閱了C99 spec標準,它是這麼說的:

Sizes of integer types <limits.h>
The values given below shall be replaced by constant expressions suitable for use in #ifpreprocessing directives.
...
...
minimum value for an object of type int
INT_MIN -32767 // −(215 − 1)           //這只是其中一個示例,不一樣平臺可能有不一樣定義
— maximum value for an object of type int
INT_MAX +32767 // 215 − 1

翻譯過來就是,int類型的大小是由limits.h文件中INT_MIN和INT_MAX兩個宏定義來決定的,而limits.h文件在編譯器庫文件中能夠找到。

int類型對應平臺的大小是這樣的:

  • 16位系統中,int型爲16位大小,兩字節
  • 32位系統中,int型爲32位大小,四字節
  • 64位系統中,int型爲32位大小,四字節

事實上,除了int類型,還有一個類型在不一樣平臺中有不一樣的表現,那就是long型:

  • 16位系統中,long型爲32位大小,4字節
  • 32位系統中,long型爲32位大小,4字節
  • 64位系統中,long型爲64位大小,8字節

指針的大小

對於指針變量的大小,我聽得最多的一個概念就是:在32位系統下指針類型爲32位,在64位系統下指針類型爲64位,以此類推。

可是不得不遺憾地說,這個說法實際上是錯誤的,至少說是不嚴謹的。

指針本質上是變量,它的值是內存中的地址,既然須要經過指針可以訪問當內存當中全部的數據,那麼這個指針類型的寬度至少要大於等於地址總線的寬度。打個比方一個芯片的地址總線是32位,那麼內存地址的範圍就是0~4G,那麼這個指針類型的寬度至少須要32位,才能保證訪問到內存中每一個字節。

可是,實際上的狀況是:芯片的位數由芯片一次能處理的數據寬度決定,可當作是數據總線的寬度,可是地址總線和數據總線的寬度有時候並不一致。

因此在經典的32位系統中,同時也是32位地址總線,天然而然的,指針的長度爲32位。

可是對早期的8086而言,這是16位芯片,可是它的地址總線卻擴展到了20位,同時由於數據對齊的緣由,它的指針大小應該是16+16位=32位,可是出於效率上的優化,8086提供了遠指針、近指針,在訪問本段內的地址時,採用16位指針,若是有段地址跳轉,就使用32位的指針。

至少從這個示例能夠知道,指針的大小徹底由實際使用的地址總線的寬度(+數據對齊)來決定,而並不是由芯片位數來決定。

因此,有時候,咱們可能會在64位系統中碰到指針大小爲4字節的狀況,也可能在16位系統中碰到指針大小爲4字節的狀況。

固然,須要特別注意的是,在64位系統中地址大小爲4字節的狀況下,並不是必定是芯片的地址總線是32位,極可能是CPU運行在只使用部分地址總線的模式下,又或者是使用32位兼容的編譯器所致,這一部分較爲複雜,本文旨在創建一個初步的概念,若是要深刻研究的話幾篇博客是不夠的,這裏暫不贅述。

總結

int和long類型數據大小並不是由硬件平臺的位數決定,而是由C標準和編譯器共同決定。

同時,指針即sizeof(ptr)的大小也並不是由硬件平臺的位數決定,而是由實際上所使用的地址總線寬度決定的。
***

好了,關於int型和指針的大小的討論就到此爲止啦,若是朋友們對於這個有什麼疑問或者發現有文章中有什麼錯誤,歡迎留言

原創博客,轉載請註明出處!

祝各位早日實現項目叢中過,bug不沾身.

相關文章
相關標籤/搜索