概念
字節(jié)序贫橙,即多字節(jié)數(shù)據(jù)在計(jì)算機(jī)內(nèi)存中存儲(chǔ)或者網(wǎng)絡(luò)傳輸時(shí)各字節(jié)的存儲(chǔ)順序。 來(lái)自百度百科
可分為小端字節(jié)序和大端字節(jié)序反粥。
小端字節(jié)序(Little Endian, LE)卢肃,低字節(jié)存儲(chǔ)在內(nèi)存低地址;高字節(jié)存儲(chǔ)在內(nèi)存高地址才顿。
大端字節(jié)序(Big Endian, BE)莫湘,低字節(jié)存儲(chǔ)在內(nèi)存高地址;高字節(jié)存儲(chǔ)在內(nèi)存低地址郑气。網(wǎng)絡(luò)字節(jié)序采用的就是大端字節(jié)序幅垮。
例如:把0x1234,兩個(gè)字節(jié)的數(shù)據(jù)寫入到0x34230000起始的內(nèi)存中尾组。
使用小端字節(jié)序:
0x34存儲(chǔ)在0x34230000中
0x12存儲(chǔ)在0x34230001中
在內(nèi)存中存儲(chǔ)如下:
低|00110100|00010010|高
使用大端字節(jié)序:
0x12存儲(chǔ)在0x34230000中
0x34存儲(chǔ)在0x34230001中
在內(nèi)存中存儲(chǔ)如下:
低|00010010|00110100|高
檢測(cè)
程序
此程序在int為占2字節(jié)以上的編譯器上執(zhí)行忙芒,下面示例的說(shuō)明是在int為4字節(jié)的編譯器上執(zhí)行的結(jié)果
// 若處理器采用的是大端模式,則返回0讳侨;若采用的是小端模式呵萨,則返回1。
int checkCPU()
{
union
{
int a;
char b;
} c;
c.a = 1;
return c.b==1;
}
剖析
由于聯(lián)合體union的存放順序是所有成員都從低地址開(kāi)始存放跨跨,利用該特性就可以輕松地獲得了CPU對(duì)內(nèi)存采用Little-Endian還是Big-Endian模式讀寫潮峦。
說(shuō)明
1、 在c中歹叮,聯(lián)合體(共用體)的數(shù)據(jù)成員都是從低地址開(kāi)始存放跑杭;
2、 若是小端模式咆耿,由低地址到高地址c.a存放為0x01 00 00 00德谅,c.b被賦值為0x01;
地址 | 0x00000000 | 0x00000001 | 0x00000002 | 0x00000003 | |
---|---|---|---|---|---|
c.a | 01 | 00 | 00 | 00 | |
c.b | 01 | 00 |
3萨螺、 若是大端模式窄做,由低地址到高地址c.a存放為0x00 00 00 01愧驱,c.b被賦值為0x0;
地址 | 0x00000000 | 0x00000001 | 0x00000002 | 0x00000003 | ||
---|---|---|---|---|---|---|
c.a | 00 | 00 | 00 | 01 | ||
c.b | 00 | 00 |
4椭盏、 根據(jù)c.b的值的情況就可以判斷cpu的模式了组砚。
轉(zhuǎn)換
程序
#include <stdio.h>
#include <stdint.h>
// 32位int大小端轉(zhuǎn)換
int32_t BigLittleSwap32(int32_t value)
{
return ((value & 0x000000FF) << 24 |
(value & 0x0000FF00) << 8 |
(value & 0x00FF0000) >> 8 |
(value & 0xFF000000) >> 24 );
}
// 64位int大小端轉(zhuǎn)換
int64_t BigLittleSwap64(int64_t value)
{
return ((value & 0x00000000000000FF) << 56 |
(value & 0x000000000000FF00) << 40 |
(value & 0x0000000000FF0000) << 24 |
(value & 0x00000000FF000000) << 8 |
(value & 0x000000FF00000000) >> 8 |
(value & 0x0000FF0000000000) >> 24 |
(value & 0x00FF000000000000) >> 40 |
(value & 0xFF00000000000000) >> 56);
}
int main()
{
int aaa = 0x1234;
printf("aaa = %d\n", aaa);
int bbb = BigLittleSwap32(aaa);
printf("bbb = %d\n", bbb);
int64_t ccc = BigLittleSwap64(aaa);
printf("ccc = %ld\n", ccc);
return 0;
}