一、概念
字节序,就是 大于一个字节类型的数据在内存中的存放顺序。是在跨平台和网络编程中,时常要考虑的问题。
二、分类
字节序经常被分为两类:
1. Big-Endian(大端):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
2.Little-Endian(小端):低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
三、高低地址与高低字节
高低地址:
C程序映射中内存的空间布局大致如下:
最高内存地址 0xFFFFFFFF
栈区(从高内存地址,往 低内存地址发展。即栈底在高地址,栈顶在低地址)
堆区(从低内存地址 ,往 高内存地址发展)
全局区(常量和全局变量)
代码区
最低内存地址 0x00000000
高低字节
在十进制中靠左边的是高位,靠右边的是低位,在其他进制也是如此。例如 0x12345678,从高位到低位的字节依次是0x12、0x34、0x56和0x78。
网络字节序 就是 大端字节序:4个字节的32 bit值以下面的次序传输,首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit
主机字节序 就是 小端字节序,现代PC大多采用小端字节序。
四、例子
对于数据 0x12345678,假设从地址0x4000开始存放,在大端和小端模式下,存放的位置分别为:
内存地址 | 小端模式 | 大端模式 |
0x4003 | 0x12 | 0x78 |
0x4002 | 0x34 | 0x56 |
0x4001 | 0x56 | 0x34 |
0x4000 | 0x78 | 0x12 |
采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。
小端存储后:0x78563412 大端存储后:0x12345678
五、代码判断当前机器是大端还是小端
void byteorder()
{
union
{
short value;
char union_bytes[sizeof(short)];
}test;
test.value = 0x0102;
if (sizeof(short) == 2)
{
if (test.union_bytes[0] == 1 && test.union_bytes[1] == 2)
cout << "big endian" << endl;
else if (test.union_bytes[0] == 2 && test.union_bytes[1] == 1)
cout << "little endian" << endl;
else
cout << "unknown" << endl;
}
else
{
cout << "sizeof(short) == " << sizeof(short) << endl;
}
return ;
}
上述代码,使用了联合体union,所有成员共用同一块内存的特性。
一般,主机字节序,都是小端模式。