17.大小端.md 3.7 KB

大小端

判别规则(核心,唯一要记的)

  • 高字节存低地址 = 大端(big-endian,"大"在前);低字节存低地址 = 小端(little-endian,"小"在前)
  • 判断法:写一个多字节值,读它的首字节(union 或指针强转)
  • 通信:网络字节序 = 大端,本机 = 小端,发送前 htonl/htons 转网络序,接收后 ntohl/ntohs 转回

一句话:"大在前是大端,小在前是小端;上网先转大端,收下再转回小端。"

抽象描述(一句话本质)

大小端 = 多字节数据在内存里的排列顺序。判断看"最低地址字节存的是高字节还是低字节"。跨设备通信/存储必须约定字节序,本机内部(如寄存器)不用转。

正反例(建立直觉)

  • 正例1int i = 0x12345678; → 小端内存 78 56 34 12,大端内存 12 34 56 78
  • 正例2(union 判断)union { int i; char c; } u; u.i = 0x12345678; u.c == 0x78 ? 小端 : 大端;
  • 正例3(指针判断)char *p = (char *)&i; *p == 0x78 ? 小端 : 大端;
  • 正例4(通信转换):小端主机发 0x12345678,直接发内存字节 78 56 34 12,大端对方按 12 34 56 78 读 → 变成 0x78563412 错了 → 发送前 htonl(0x12345678),对方 ntohl 转回
  • 反例1:以为所有平台字节序一样 → 错
  • 反例2:以为 union 只能测 int → 任何多字节类型都行

易混对比

小端 little-endian 大端 big-endian
低地址存 低字节(小的在前) 高字节(大的在前)
代表平台 x86、ARM 主流 网络协议、MIPS 部分、某些 MCU
记忆 "小"在前 → 小端 "大"在前 → 大端

变体验证(3 题,全过=学会)

  1. 大端平台 union { int i; char c; } u; u.i = 0x11223344;u.c = 0x11(大端高字节在低地址)
  2. 陷阱题:小端设备发大端设备 uint16_t 0x0001 → 发送前用 htons(16 位用 short 版本,32 位才用 htonl);直接发字节序不一致会错值
  3. 陷阱题:嵌入式读寄存器不用转(本机内部,处理器自己管字节序);只有跨设备通信/存储才需要

口述要点(面试怎么讲)

  • 结论先行:高字节放低地址 = 大端,低字节放低地址 = 小端
  • 判断方法:union 或指针强转读首字节——char *p = (char*)&i; (*p == 0x78) ? 'l' : 'h';
  • 为什么网络用大端:像写字一样从左往右读,人类阅读友好;网络协议早期定义时就选了大端
  • 哪些场景要转字节序:网络通信(htonl/htons/ntohl/ntohs)、跨平台二进制文件(BMP、嵌入式文件系统、Flash 配置表)、和 PC 工具交互的二进制数据。缩写:MIPS(一种 RISC 处理器架构,部分用大端)、MCU(Microcontroller Unit 微控制器,多数小端)
  • 寄存器不用转:本机内部,处理器自己管理字节序
  • 易错点:uint16_t 用 htons 不是 htonl;跨设备必转、本机内不转

关系网络

相邻概念 和本主题的关系 孤立理解会犯的错
struct vs union union 测大小端:共用起始地址读首字节 忘了 union 成员同地址
通信协议 网络字节序 = 大端,本机 = 小端,收发前 htonl/ntohl 直接发内存字节序导致错值
结构体对齐/pack 协议帧 pack(1) + 字节序,两个一起考 只处理对齐忘了转字节序
嵌入式调试 和 PC 工具交换二进制数据要转字节序 以为本机内转来转去没用

学习日期

2026-08-03


每主题一页,复习时只翻本目录。