0%

字节序

字节序的问题在不同硬件,系统,或者在网络交互时都需要格外注意

字节顺序 Endian

现代计算机系统一般以字节 (Byte, 8bit) 为单位作为逻辑寻址单位, 当数据单位的长度大于 1 字节时,就要区分字节顺序 , 常见字节顺序有两种: Big Endian (BE), Little Endian (LE)

  • 大端存储 (BE): 低位地址存放高位字节
  • 小端存储 (LE): 低位地址存放低位字节

例如: 4 字节无符号整数 0xAB CC DD EF, 最高位字节是 0xAB, 最低位字节是 0xEF

内存: |0x01|0x02|0x03|0x04|

若数据存储在内存地址 0x01 的位置上,占用 [0x01, 0x04] 4 个字节

大小端就看低位地址 (0x01) 上存储的是高位字节 (0xAB) 还是低位字节 (0xEF)

常见环境的字节序

一般操作系统上的字节序是由 CPU 和操作系统决定

  • Intel X86 平台全部采用小端模式
  • ARM 即可以工作在大端模式,也可以工作在小端模式
  • STM32 属于小端模式

X86 和一般操作系统使用小端模式 (Windows, Linux), 但 MacOS 是大端模式

网络字节序: TCP/IP 协议中规定的字节序,与环境无关, 网络字节序采用大端模式 (Big Endian)

编程判断当前环境字节序

1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
#include <stdio.h>
int main()
{
uint32_t num = 0x00'00'00'01; // C++14开始支持以单引号分隔数字, 若不支持可以删掉
unsigned char b = *(unsigned char*)(&num); // 低地址取1字节, 解析为unsigned char
if (b == 0) { printf("Big Endian\n"); }
else { printf("Little Endian\n"); }
return 0;
}