1. 程式人生 > >【C/C++開發】【VS開發】win32位與x64位下各型別長度對比

【C/C++開發】【VS開發】win32位與x64位下各型別長度對比

64 位的優點:64 位的應用程式可以直接訪問 4EB 的記憶體和檔案大小最大達到4 EB(2 的 63 次冪);可以訪問大型資料庫。本文介紹的是64位下C語言開發程式注意事項。

1. 32 位和 64 位C資料型別

32和64位C語言內建資料型別,如下表所示:


上表中第一行的大寫字母和數字含義如下所示:
I表示:int型別
L表示:long型別
P表示:pointer指標型別
32表示:32位系統
64表示64位系統

如:LP64表示,在64位系統下的long型別和pointer型別長度為64位。
64位Linux 使用了 LP64 標準,即:long型別和pointer型別長度為64位,其他型別的長度和32位系統下相同型別的長度相同,32位和64位下型別的長度比較見上圖的藍色部分。
下圖為在32和64位linux系統下使用sizeof檢測出的資料型別的長度。
32位平臺下結果:


64位平臺下結果:


2. 64系統下開發注意事項:

2.1 格式化字串:long使用%ld,指標使用%p,例如:

[cpp] view plain copy  print?
  1. char *ptr = &something;  
  2. printf (%x\n", ptr);  

上面的程式碼在 64 位系統上不正確,只顯示低 4 位元組的內容。正確的方法是:使用 %p,如下:
[cpp] view plain copy  print?
  1. char *ptr = &something;  
  2. printf (%p\n", ptr);  

2.2 數字常量:常量要加L


例1,常數 0xFFFFFFFF 是一個有符號的 long 型別。在 32 位系統上,這會將所有位都置位(每位全為 1),但是在 64 位系統上,只有低 32 位被置位了,結果是這個值是 0x00000000FFFFFFFF。
例2,在下面的程式碼中,a 的最大值可以是 31。這是因為 1 << a 是 int 型別的。

[cpp] view plain copy  print?
  1. long l = 1 << a;  
要在 64 位系統上進行位移,應使用 1L,如下所示: [cpp] view plain copy  print?
  1. long l = 1L << a;  
2.3 符號擴充套件:避免有符號數與無符號數運算,例如:
[cpp] view plain copy  print?
  1. int i = -2;  
  2. unsigned int j = 1;  
  3. long l = i + j;  
  4. printf("Answer: %ld\n",l);  
32位下是-1,在64位下是4294967295。原因在於表示式(i+j)是一個unsigned int表示式,但把它賦值給k時,符號位沒有被擴充套件。要解決這個問題,兩端的運算元只要均為signed或均為unsigned就可。

2.4 轉換截斷:
轉換截斷髮生在把long轉換成int時,如下例: [cpp] view plain copy  print?
  1. int length = (int) strlen(str);  
strlen返回size_t(它在LP64中是unsigned long),當賦值給一個int時,截斷是必然發生的。而通常,截斷只會在str的長度大於2GB時才會發生,這種情況在程式中一般不會出現。雖然如此,也應該儘量使用適當的多型型別(如size_t、uintptr_t等等)。

2.5 賦值:
不要交換使用 int 和 long 型別,例如:

[cpp] view plain copy  print?
  1. int i;  
  2. time_t l;  
  3. i = l;  

不要使用 int 型別來儲存指標,例如:

[cpp] view plain copy  print?
  1. unsigned int i, *ptr;  
  2. i = (unsigned) ptr;  

不要使用指標來存放 int 型別的值。例如:

[cpp] view plain copy  print?
  1. int *ptr;  
  2. int i;  
  3. ptr = (int *) i;  

2.6 移植倒64位環境下的效能

移植到64位平臺後,效能實際上降低了。原因是64位中的指標長度和資料大小有關,並由此引發的快取命中率降低、資料對齊等問題。通過改變結構中資料排列的先後順序,會因為少了填充資料,儲存空間也隨之減少。如:


2.7 程式中連結到的庫要使用64位的庫。

由上可見所有的問題都是由long和指標長度改變引起,在開發過程中只有牢記long和指標型別的長度。