數據模型(LP32 ILP32 LP64 LLP64 ILP64 )


數據模型(LP32 ILP32 LP64 LLP64 ILP64 )

 

32位環境涉及"ILP32"數據模型,是因為C數據類型為32位的int、long、指針。而64位環境使用不同的數據模型,此時的long和指針已為64位,故稱作"LP64"數據模型。

現今所有64位的類Unix平台均使用LP64數據模型,而64位Windows使用LLP64數據模型,除了指針是64位,其他基本類型都沒有變。

 

Data Type ILP32 LP32 ILP64 LP64 LLP64
宏定義   _     _     _   __LP64__ __LLP64__
平台 Win32 API / Unix 和 Unix 類的系統 (Linux,Mac OS X) Win16 API   Unix 和 Unix 類的系統 (Linux,Mac OS X) Win64 API
char 8 8 8 8 8
short 16 16 16 16 16
int 32 32 64 32 32
long 32 32 64 64 32
long long 64 64 64 64 64
pointer 32 32 64 64 64

 

在這張表中,LP64,ILP64,LLP64是64位平台上的字長模型,ILP32和LP32是32位平台上的字長模型。

LP64意思是long和pointer是64位,

ILP64指int,long,pointer是64位,

LLP64指long long和pointer是64-bit的。

ILP32指int,long和pointer是32位的,

LP32指long和pointer是32位的。

 

float 都是4字節;
double 都是8字節;(C中直接寫小數,默認是double型)

 

這 3 個 64 位模型(LP64、LLP64 和 ILP64)之間的區別在於非浮點數據類型。當一個或多個 C 數據類型的寬度從一種模型變換成另外一種模型時,應用程序可能會受到很多方面的影響。這些影響主要可以分為兩類:

  • 數據對象的大小。編譯器按照自然邊界對數據類型進行對齊;換而言之,32 位的數據類型在 64 位系統上要按照 32 位邊界進行對齊,而 64 位的數據類型在 64 位系統上則要按照 64 位邊界進行對齊。這意味着諸如結構或聯合之類的數據對象的大小在 32 位和 64 位系統上是不同的。

  • 基本數據類型的大小。通常關於基本數據類型之間關系的假設在 64 位數據模型上都已經無效了。依賴於這些關系的應用程序在 64 位平台上編譯也會失敗。例如,sizeof (int) = sizeof (long) = sizeof (pointer) 的假設對於 ILP32 數據模型有效,但是對於其他數據模型就無效了。

總之,編譯器要按照自然邊界對數據類型進行對齊,這意味着編譯器會進行 “填充”,從而強制進行這種方式的對齊,就像是在 C 結構和聯合中所做的一樣。結構或聯合的成員是根據最寬的成員進行對齊的。

 

 

 

 數據類型轉換原則

 

 

 

 

結構體對齊,默認對齊原則:
1.數據類型對齊值:
        char型數據自身對齊值為1
        short為2,int、float為4,double為8(windows)
        解釋:
                char變量只要有一個空余的字節即可存放
                short要求首地址能被2整除
                int、float、double同理
2.結構體的對齊值:
        其成員中自身對齊值最大的那個值。
        解釋:
                結構體最終對齊按照數據成員中最長的類型的整數倍

指定對齊原則:
使用#pragma pack改變默認對其原則
格式:
#pragma pack (value)時的指定對齊值value。
結構體最終對齊按照指定對齊值的整數倍
注意:
1.value只能是:1 2 4 8等
2.指定對齊值與數據類型對齊值相比取較小值
如:如果指定對齊值:
設為1:則short、int、float等均為1
設為2:則char仍為1,short為2,int 變為2

 

移位運算
左移<<
        將一個數的二進制位左移,高位丟棄,低位補0
        例:a = a<<2 將a的二進制數左移2位,右補0
        若a=15,即二進制數0 0 0 01111
        左移2位得0 011110 0,(十進制數60)
>>算術右移
        有符號數,如果為正數,則左邊移入0,右邊丟棄
        如果為負數,左邊移入1,右邊丟棄
>>邏輯右移
        不關心正數、負數,左邊均移入0,右邊丟棄
        算術或者邏輯右移,由編譯器決定

 

博主今天在寫代碼的時候遇到一個奇怪的問題,程序的要求是實現一個int的移位操作,不管左移還是右移,空出來的位置通通置0即邏輯移位。一開始沒注意太多直接用了<<和>>移位操作符,結果卻發現實現是錯誤的==!
經過查證發現,c語言中的移位操作符,在左移時執行的是邏輯移位,在右移時執行的是算術移位。那怎么用>>實現右移操作呢?
又經過查證得知,無符號數的移位操作都是執行的邏輯移位。那么要想用>>實現邏輯右移就可以將操作數強制類型轉化為unsigned類型,如下:

int a = 0xfffffffe;
int b = (unsigned int)a >> 1;


執行的結果是2147483647即7fffffff,可見其右移后左端補的是0。
綜上:C語言中移位操作符實現的是邏輯左移和算術右移,但是算術左移和邏輯左移的效果相同,算術右移和邏輯右移的效果不同,要實現邏輯右移可將操作數強制類型轉化為無符號數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM