字节序(Byte Order)
“endian”这个词出自讽刺小说《格列佛游记》。小人国的内战就源于吃水煮鸡蛋时究竟是从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过6次叛乱,其中一个皇帝送了命,另一个丢了王位。
实例
- 大小端与CPU有关,与编译器和操作系统类型无关;
- x86、arm是小端,MAC是大端,MIPS可以配置;
- TCP/IP协议、Java虚拟机规定为大端模式。
定义
MSB(Most Significant Bit/Byte)通常用来表明在一个bit序列(如一个byte是8个bit组成的一个序列) 或一个byte序列(如word是两个byte组成的一个序列)中对整个序列取值影响最大的那个bit/byte。LSB(Least Significant Bit/Byte)通常用来表明在一个bit序列(如一个byte是8个bit组成的一个序列) 或一个byte序列(如word是两个byte组成的一个序列) 中对整个序列取值影响最小的那个bit/byte。
- 大端存储(高尾端):字数据的MSB存储在低地址中
- 小端存储(低尾端):字数据的MSB存储在高地址中
举个🌰
0x11223344
,0x11
是MSB,0x44
是LSB
地址 | 大端 | 小端 |
---|---|---|
0x0 | 0x11 | 0x44 |
0x1 | 0x22 | 0x33 |
0x2 | 0x33 | 0x22 |
0x3 | 0x44 | 0x11 |
判断大小端
方式一:使用强制类型转换
#include <iostream>
using namespace std;
int main()
{
int a = 0x1234;
//由于int和char的长度不同,借助int型转换成char型,只会留下低地址的部分
char c = (char)(a);
if (c == 0x12)
cout << "big endian" << endl;
else if(c == 0x34)
cout << "little endian" << endl;
}
方式二:巧用union联合体
#include <iostream>
using namespace std;
//union联合体的重叠式存储,endian联合体占用内存的空间为每个成员字节长度的最大值
union endian
{
int a;
char ch;
};
int main()
{
endian value;
value.a = 0x11223344;
//a和ch共用4字节的内存空间
if (value.ch == 0x12)
cout << "big endian"<<endl;
else if (value.ch == 0x34)
cout << "little endian"<<endl;
}
参考资料
《程序员的自我修养》