嵌入式 C:字节序(大端/小端)
更新时间:2026-09-21。嵌入式/裸机视角。跨端序转换见 端序转换。
一句话回答
字节序就是「一个多字节数在内存里按什么顺序摆放」:小端把最低位字节放在最低地址(ARM Cortex-M、x86),大端把最高位字节放在最低地址(网络协议、部分传感器/总线);同一个 uint32_t 数值,两种方式在内存中的字节排列正好相反。
一、用一个数看排列
0x12345678,从低地址到高地址:
| 地址 | 小端(LE) | 大端(BE) |
|---|---|---|
| +0 | 0x78 | 0x12 |
| +1 | 0x56 | 0x34 |
| +2 | 0x34 | 0x56 |
| +3 | 0x12 | 0x78 |
- 小端:最低有效字节(LSB)
0x78在最低地址; - 大端:最高有效字节(MSB)
0x12在最低地址,符合人的书写顺序。
二、程序里判断当前字节序
c
uint16_t x = 0x0001;
uint8_t *p = (uint8_t *)&x;
if (p[0] == 0x01) {
/* 小端:低地址存到的是 0x01 */
} else {
/* 大端 */
}三、嵌入式为什么必须关心
- 串口/网络通信:很多协议规定大端(TCP/IP 用「网络字节序」即大端),而 MCU 多为小端,收发多字节字段必须转换;
- 外设与传感器:部分寄存器块、EEPROM、CAN/J1850 数据按大端组织;
- DMA/缓冲区:把
uint32当字节流搬运或解析时,字节顺序决定解析结果; - 共享固件/镜像:在大小端机器间交换二进制数据需明确约定。
常见坑
- 把内存字节序和寄存器位域编号混淆:
bit0是寄存器内的最低位,与字节在内存中的排列是两个层面。 - 只在本机调试正常:两个同端序设备互通没问题,一旦接入大端传感器/网络协议数据就错位。
- 用
memcpy后按字节硬猜:应先确认双方字节序,再做显式转换而非依赖运气。 - 结构体整体跨端序传输:除字节序外还有对齐/填充问题,见 packed 与对齐。
总结
字节序规定多字节数据在内存中的字节摆放:小端低字节在低地址(Cortex-M/x86),大端高字节在低地址(网络字节序);MCU 处理通信协议、外设寄存器块和二进制数据时必须确认并显式转换。主机/跨平台视角另见 字节序与位操作。