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位平台下結果:
指針類型變化到8字節,,long類型變化到8字節
2 64系統下開發注意事項2.1 格式化字符串:long使用%ld,指針使用%p,例如:
char *ptr =& something;
printf (%x\n", ptr);
上面的代碼在 64 位系統上不正確,只顯示低 4 字節的內容。正確的方法是:使用 %p。
char *ptr =& something;
printf (%p\n", ptr);
2.2 數字常量:常量要加L
例1,常數 0xFFFFFFFF 是一個有符號的 long 類型。在 32 位系統上,這會將所有位都置位(每位全為 1),但是在 64 位系統上,只有低 32 位被置位了,結果是這個值是 0x00000000FFFFFFFF。
例2,在下面的代碼中,a 的最大值可以是 31。這是因為 1<< a 是 int 類型的。
long l = 1<< a;
要在 64 位系統上進行位移,應使用 1L,如下所示:
long l = 1L<< a;
2.3 符號擴展:避免有符號數與無符號數運算,例如:
int i = -2;
unsigned int j = 1;
long l = i + j;
printf("Answer: %ld\n",l);
32位下是-1,在64位下是4294967295。原因在於表達式(i+j)是一個unsigned int
表達式,但把它賦值給k時,符號位沒有被擴展。要解決這個問題,兩端的操作數只要均為signed或均為unsigned就可。
2.4 轉換截斷
轉換截斷發生在把long轉換成int時,如下例:
int length = (int) strlen(str);
strlen返回size_t(它在LP64中是unsigned long),當賦值給一個int時,截斷是必然發生的。而通常,截斷只會在str的長度大於2GB時才會發生,這種情況在程序中一般不會出現。雖然如此,也應該盡量使用適當的多態類型(如size_t、uintptr_t等等)。
2.5 賦值,
不要交換使用 int 和 long 類型,例如:
int i;
time_t l;
i = l;
不要使用 int 類型來存儲指針,例如:
unsigned int i, *ptr;
i = (unsigned) ptr;
不要使用指針來存放 int 類型的值。例如:
int *ptr;
int i;
ptr = (int *) i;
2.6 移植倒64位環境下的性能
移植到64位平台後,性能實際上降低了。原因是64位中的指針長度和數據大小有關,並由此引發的緩存命中率降低、數據對齊等問題。通過改變結構中數據排列的先後順序,會因為少了填充數據,存儲空間也隨之減少。如:
2.7 程序中鏈接到的庫要使用64位的庫。
由上可見所有的問題都是由long和指針長度改變引起,在開發過程中只有牢記long和指針類型的長度。
轉自:;http://blog.sina.com.cn/s/blog_57421ff80100c7g1.html