溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c++32位程序和64位程序的區(qū)別有哪些

發(fā)布時(shí)間:2021-11-01 16:56:49 來(lái)源:億速云 閱讀:825 作者:iii 欄目:編程語(yǔ)言

這篇文章主要講解了“c++32位程序和64位程序的區(qū)別有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“c++32位程序和64位程序的區(qū)別有哪些”吧!

代碼上的區(qū)別

實(shí)際上,對(duì)于32位程序和64位程序來(lái)說,代碼上的區(qū)別不大,嚴(yán)格來(lái)說,甚至是一樣的,它的主要區(qū)別在于一些基本數(shù)據(jù)類型占用的字節(jié)長(zhǎng)度不一樣(注:這里僅針對(duì)類Unix平臺(tái))

類型32位占用字節(jié)64位占用字節(jié)
long48
unsigned long48
指針48

當(dāng)然這里的long包括一些用它定義的類型,如time_t,它的長(zhǎng)度也是有區(qū)別的,關(guān)于time_t,還有一個(gè)有意思的問題《什么是2038問題》。

除此之外,其默認(rèn)對(duì)齊字節(jié)數(shù),也不一樣,32位程序?yàn)?字節(jié),64位程序默認(rèn)為8字節(jié)。關(guān)于字節(jié)對(duì)齊,可參考《理一理字節(jié)對(duì)齊的那些事》。

可執(zhí)行文件上的區(qū)別

來(lái)看個(gè)小例子吧,看看他們有何區(qū)別。

//來(lái)源:公眾號(hào)編程珠璣 //作者:守望先生 test.c #include<stdio.h> struct Test {   int a;   long b; }; int main(void) {     printf("sizeof(long) = %zu\n",sizeof(long)); //long類型占用字節(jié)數(shù)     printf("sizeof(unsigned long) = %zu\n",sizeof(unsigned long));//unsigned long類型占用字節(jié)數(shù)     struct Test test = {1,2};     printf("sizeof(struct Test) = %zu\n",sizeof(test));//用于測(cè)試對(duì)齊字節(jié)數(shù)     printf("sizeof(pointer) = %zu\n",sizeof(&test)); //指針占用字節(jié)數(shù)     return 0; }

如果你的系統(tǒng)是64位,默認(rèn)編譯為64位程序,而如果需要編譯為32位程序,則需要帶上-m32參數(shù),如果你的系統(tǒng)是32位的,那么是不能直接運(yùn)行64位程序的,但是如果是64位的,是可以運(yùn)行32位程序的。(實(shí)際上你在下載軟件的時(shí)候需要選擇位數(shù)的時(shí)候,就需要注意了,如果你的系統(tǒng)32位的,  但是你下載了一個(gè)64位的程序包,自然是不可用的,但是反過來(lái)卻可以。)

編譯為32位程序運(yùn)行:

$ gcc -o  test32 test.c -m32 $ ./test32 sizeof(long) = 4 sizeof(unsigned long) = 4 sizeof(struct Test) = 8 sizeof(pointer) = 4

編譯位64位程序運(yùn)行:

$ gcc -o test64 test.c  $ ./test64  sizeof(long) = 8 sizeof(unsigned long) = 8 sizeof(struct Test) = 16 sizeof(pointer) = 8

通過運(yùn)行結(jié)果,我們也可以看出前面提到的差別。

那么可執(zhí)行文件本身有什么差別呢?

$ readelf -h test32 ELF Header:   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00    Class:                             ELF32   Data:                              2's complement, little endian   Version:                           1 (current)   OS/ABI:                            UNIX - System V   ABI Version:                       0   Type:                              EXEC (Executable file)   Machine:                           Intel 80386   (...)

可以看到Class屬性標(biāo)識(shí)為ELF32。

而對(duì)于64位:

readelf -h test64 ELF Header:   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00    Class:                             ELF64   Data:                              2's complement, little endian   Version:                           1 (current)   OS/ABI:                            UNIX - System V   ABI Version:                       0   Type:                              EXEC (Executable file)   Machine:                           Advanced Micro Devices X86-64

它的屬性為ELF64。實(shí)際上我們可以通過readelf發(fā)現(xiàn)很多信息。

例如你在進(jìn)行交叉編譯后出現(xiàn)鏈接錯(cuò)誤或者最后的執(zhí)行程序在目標(biāo)機(jī)器無(wú)法運(yùn)行,則可以查看Machine部分,看看程序是否能在你想要的平臺(tái)運(yùn)行。

例如64位程序中的Machine中顯示的是Advanced Micro Devices X86-64,至少說明它在arm平臺(tái)是沒法正常運(yùn)行的。

一個(gè)程序最大能申請(qǐng)多少內(nèi)存空間?

還記得這道面試題嗎?如果你只是回答Linux理論最大不超過3G,windows不超過G,那肯定是不完整的,這里必須要區(qū)分32位程序和64位程序。

這一點(diǎn)在《解引用NULL為什么會(huì)掛死?》中已經(jīng)有所提及。32位決定了其虛擬地址空間的最大值為2^32,即4G,除去操作系統(tǒng)占用的1G左右,剩下3G左右,當(dāng)然了這里面3G包含了所有代碼,數(shù)據(jù)等,總結(jié)就是,最終能使用的不超過3G。不到3G的地址空間。(注這里并不表示它只能訪問計(jì)算機(jī)4G的內(nèi)存,而是表示最大尋址范圍為4G)。那么64位的虛擬地址空間擴(kuò)展到了17179869184G,所以,看出差別了嗎?

通過上面簡(jiǎn)單的分析可以發(fā)現(xiàn),64位程序理論能使用的內(nèi)存是驚人的,而32位程序卻非常有限,除此之外,還有一個(gè)在《什么是2038問題》》中提到的問題,就是2038年后,32位程序?qū)⒑茈y正常使用時(shí)間相關(guān)的處理。

當(dāng)然了,64位系統(tǒng)通常能夠支持更高精度的浮點(diǎn)運(yùn)算。

同時(shí)支持32位和64位代碼編寫原則

基于前面提到的原因,很多傳統(tǒng)系統(tǒng)都開始著手移植到64位系統(tǒng)上,而如果原先代碼就非常規(guī)范的話,移植工作還算比較輕松,鏈接64位庫(kù),編譯成64位程序即可,但是如果沒有遵循以下原則,那么工作量就比較大了:

依賴long類型和指針類型占用空間大小以及其表示范圍

當(dāng)然,對(duì)于這個(gè)原則,其表現(xiàn)可能非常多。

long和int混用

例如:

void test(long len) {     int localLen = len;     xxxx; }

這里很明顯可能會(huì)發(fā)現(xiàn)截?cái)?。最常見的就是?/p>

int len = sizeof(xxx);

當(dāng)然,這里大多數(shù)情況下也不會(huì)有太大問題,直到其長(zhǎng)度大于int表示范圍。

慎用掩碼定義

我們可能經(jīng)常需要定義一些掩碼:

long mask = OxFFFFFFFFL;

在 32 位系統(tǒng)上,這會(huì)將所有位都置位(每位全為 1),但是在 64 位系統(tǒng)上,只有低 32 位被置位了。結(jié)果是這個(gè)值是  0x00000000FFFFFFFF。

如果希望所有位置1,那么可以:

long mask = 1L << ((sizeof(long) * 8) - 1);

打印指針

32下,這樣的沒問題的:

int a = 10; int *p = &a; printf("%x",p);

但是64位下,打印不完全。自然要使用:

printf("%p",p);

傳送結(jié)構(gòu)體數(shù)據(jù)

在32位和64位系統(tǒng)中,其默認(rèn)對(duì)齊字節(jié)數(shù)是不一樣的。

strcut test {     int a;     long b; }

如果對(duì)方是64位,發(fā)送過來(lái)上述結(jié)構(gòu)體數(shù)據(jù),而你的是32位程序,可想而知,結(jié)果并不會(huì)如你所愿。前面占用空間16字節(jié),而后者占用空間8字節(jié)。

顯示定義long

如果你的數(shù)據(jù)類型是long,那么可以使用L顯示說明:

long i = 1 << a;

上面的寫法建議換成:

long i  = 1L << a;

避免數(shù)據(jù)被截?cái)唷?/p>

感謝各位的閱讀,以上就是“c++32位程序和64位程序的區(qū)別有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)c++32位程序和64位程序的區(qū)別有哪些這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI