| 模式 | 低地址存放 | 高地址存放 | 典型架構 |
|---|---|---|---|
| 大端 | 高位字節 | 低位字節 | 网络字節序、PowerPC、SPARC |
| 小端 | 低位字節 | 高位字節 | x86、x64、ARM (默認) |
例:0x12345678 在小端機上內存佈局(地址遞增):78 56 34 12。
bool is_little_endian() {
int val = 0x12345678;
char *p = (char *)&val; // char* 逐字節訪問
return p[0] == 0x78; // 低地址存低位 → 小端
}
也可用 short / union 變體。
bool is_little_endian() {
union {
int i;
char c[4];
} u;
u.i = 0x12345678;
return u.c[0] == 0x78;
}
u.c[0]..u.c[3] 觀察完整字節序。
bool is_little_endian() {
int val = 1; // 0x00000001
return (*(char *)&val) == 1; // 等價判斷最低字節是否為 1
}
最簡潔,利用 1 的二進制只有最低位為 1。
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ (GCC/Clang),#ifdef _WIN32 (Windows 均為小端)。
#include // 或
// 主機序 → 網絡序 (大端)
uint16_t port_net = htons(port_host);
uint32_t ip_net = htonl(ip_host);
// 網絡序 → 主機序
uint16_t port_host = ntohs(port_net);
uint32_t ip_host = ntohl(ip_net);
鐵律:所有進出網絡的整數必須轉換,即使當前機器是大端(遷移時免改代碼)。
#pragma pack(1)
struct Packet {
uint32_t magic; // 需 htonl
uint16_t len; // 需 htons
char data[];
};
#pragma pack()
#pragma pack(1) 消除填充,但不處理字節序。hton*,接收後 ntoh*。