商務(wù)網(wǎng)站建設(shè)綜合實訓(xùn)信陽網(wǎng)絡(luò)推廣公司
1. 大小端介紹
-
大端(Big Endian)和小端(Little Endian)是兩種CPU或者計算機系統(tǒng)存儲數(shù)據(jù)的方式。
-
在大端系統(tǒng)中,數(shù)據(jù)的高位字節(jié)(MSB)存儲在內(nèi)存地址的低位,低位字節(jié)(LSB)存儲在內(nèi)存地址的高位,這種存儲方式類似于閱讀習(xí)慣,從左到右。
-
在小端系統(tǒng)中,數(shù)據(jù)的低位字節(jié)存儲在內(nèi)存地址的低位,高位字節(jié)存儲在內(nèi)存地址的高位,這種存儲方式和我們平時閱讀數(shù)字的順序是一致的,從右到左。假如我們有一個十六進制數(shù)
0x12345678
占用四個字節(jié),如果它是大端存儲將是以下畫面:
因為
12
是十六進制數(shù)0x12345678
的高位,它存在低地址位中,因此是高位字節(jié)存儲在低內(nèi)存地址,因此是大端存儲,這也看起來符合人的思維
如果它小端存儲則是以下畫面
這看起來就很反人類阿,低字節(jié)的
78
存在了左邊,但是字面上卻合順,即低字節(jié)存在地址低字節(jié)。這就是小端存儲。
2. 使用union判斷大小端
2.1 union內(nèi)存處理方式
union內(nèi)存特點主要有如下:
- 聯(lián)合體的所有成員相對于基地址的偏移量為0
- 聯(lián)合的內(nèi)存大小等于其中最大成員的大小。
- 聯(lián)合的所有成員共享同一塊內(nèi)存區(qū)域,即它們的存儲位置是相同的。
- 其對其方式要適合于聯(lián)合體中所有類型的成員
用人話講就是:
- 聯(lián)合體要大于等于最長的一個結(jié)構(gòu)變量的空間
- 聯(lián)合體變量的各個成員都是從低字節(jié)開始公用的(這是最重要的)
2.2 使用union判斷大小端
#include <stdio.h>int check_ending()
{union{int a;char b;}c;c.a = 1;return c.b == 1;
}int main()
{if (check_ending()) printf("the little end!");else printf(" the big end");
}
代碼中使用了一個聯(lián)合體c來測試CPU字節(jié)序。聯(lián)合體中包含了一個int類型的成員a和一個char類型的成員b。因為int類型占據(jù)了4個字節(jié),而char類型只占據(jù)了一個字節(jié),所以當聯(lián)合體中的整型變量a被設(shè)置為1時,如果該CPU是小端序,它在內(nèi)存中的存儲順序?qū)?x01 00 00 00,而char類型變量b所占據(jù)的第一個字節(jié)的值應(yīng)該為1。如果是大端序,它在內(nèi)存中的存儲順序?qū)?x00 00 00 01,而char類型變量b所占據(jù)的第一個字節(jié)的值應(yīng)該為0。
最后,在main函數(shù)中根據(jù)checkCPU()的返回值輸出對應(yīng)的信息,告知當前CPU的字節(jié)序。如果checkCPU()返回true,則表示當前CPU是小端序,輸出"The endian of cpu is little \n";如果checkCPU()返回false,則表示當前CPU是大端序,輸出"The endian of cpu is big \n"。
畫圖講解:
c+-------+
a | | 0x00000001+-------+
b | 01 | 0x01+-------+小端序:
c.a = 0x00000001,在內(nèi)存中的存儲順序為:
+----+----+----+----+
| 01 | 00 | 00 | 00 |
+----+----+----+----+
c.b 的值為0x01,低地址存放低字節(jié),因此判斷為小端序,由于b也是從低字節(jié)開始存儲數(shù)據(jù),因此b的數(shù)值和a一樣。大端序:
c.a = 0x00000001,在內(nèi)存中的存儲順序為:
+----+----+----+----+
| 00 | 00 | 00 | 01 |
+----+----+----+----+
c.b 的值為0x00,低地址存放高字節(jié),因此判斷為大端序,a的低字節(jié)位1存在了內(nèi)存的高地址上,b卻仍然從低地址位讀數(shù)據(jù),因此是0