計算機存儲多字節數據時,字節序(Endianness)決定了高低位字節在內存中的排列順序。理解大端(Big-Endian)與小端(Little-Endian)的區別,對網絡編程、文件格式解析、嵌入式開發、跨平台數據交互至關重要。
| 模式 | 內存低地址存儲 | 內存高地址存儲 | 直觀類比 |
|---|---|---|---|
| 大端模式 (Big-Endian) |
高位字節(Most Significant Byte) | 低位字節(Least Significant Byte) | 人類閱讀順序:從左到右寫高位到低位 |
| 小端模式 (Little-Endian) |
低位字節 | 高位字節 | 地址增長方向與權值增長方向一致 |
假設變量 x 起始地址為 0x0010:
| 地址 | 大端模式 | 小端模式 (x86/ARM 常見) |
|---|---|---|
| 0x0010 | 0x12 (最高位) | 0x78 (最低位) |
| 0x0011 | 0x34 | 0x56 |
| 0x0012 | 0x56 | 0x34 |
| 0x0013 | 0x78 (最低位) | 0x12 (最高位) |
(char*)&x 直接取最低字節),汇編編程、小數據塊操作效率略高。#include <stdio.h>
#include <stdint.h>
int main() {
uint32_t x = 0x12345678;
uint8_t *p = (uint8_t *)&x;
printf("Byte order: %02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);
if (p[0] == 0x78) puts("Little-Endian");
else if (p[0] == 0x12) puts("Big-Endian");
else puts("Unknown");
return 0;
}
輸出(x86_64):Byte order: 78 56 34 12 → Little-Endian。
跨機器通信必須約定字節序,TCP/IP 標準規定網絡字節序 = 大端。Linux 提供轉換宏(<arpa/inet.h>、<netinet/in.h>):
| 函數/宏 | 含義 | 示例 |
|---|---|---|
htons() | Host TO Network Short (16 位) | uint16_t port = htons(8080); |
htonl() | Host TO Network Long (32 位) | uint32_t ip = htonl(0xC0A80101); |
ntohs() | Network TO Host Short | uint16_t port = ntohs(hdr->port); |
ntohl() | Network TO Host Long | uint32_t ip = ntohl(hdr->ip); |
鐵律:發送前必須 hton*,接收後必須 ntoh*。在大端機器上這些宏為空操作,在小端機器上執行字節交換,代碼可移植。
EI_DATA 標誌指定)。gdb:set endian big/little 切換顯示模式;x/4xb &x 查看原始字節。hexdump -C file.bin / od -tx1:查看文件原始字節序。lscpu | grep Byte:查看 CPU 字節序。hton/ntoh 族函數。掌握字節序本質,是寫出可移植、健壯系統代碼的基本功。