网络通信的字节序
把“顺序”分成两种,一定先分清!
顺序名字 | 决定它的人 | 影响的范围 |
---|---|---|
写入顺序(逻辑顺序) | 你(在代码里写出来的先后) | 所有类型:char 、int 、double …… |
字节序(Endian) | CPU + 操作系统 | 只影响“一个值占多个字节”的数值类型 |
1 字符串的“写入顺序”完全由你掌控
const char str[] = "ABC";
你写的先后就是 A → B → C → '\0'。
编译器照着你的顺序一字节一字节放到内存——它根本不需要再“重新排列”:
地址递增 ↑
+------+------+------+------+
| 0x41 | 0x42 | 0x43 | 0x00 |
+------+------+------+------+'A' 'B' 'C' '\0'
-
每个元素就是 1 字节,不需要再拼成大数字。
-
CPU 不会因为是小端还是大端去倒腾它——它已经是最终形态。
➜ 所以 只要你不自己把它倒过来写,内存里永远是 “ABC\0”。
不存在“系统偷偷给你变成 CBA”的情况。
2 为什么 int
、float
才会被“倒过来”?
int x = 0x12345678; // 4 字节一个值
CPU 要先拿到这 4 个字节,然后再“解释”它们到底是哪一位是高位、哪一位是低位。
这就是 字节序 要做的事——它只在“多字节合成一个数”时介入。
-
小端:把最低有效字节放在最低地址
→ 存放顺序 78 56 34 12 -
大端:把最高有效字节放在最低地址
→ 存放顺序 12 34 56 78
📝 这一步 是硬件规定的,程序员写
0x12345678
时并不知道将来会怎么排。
因而跨机器要用htonl / ntohl
统一到“网络字节序”。
3 再看“多字节字符编码”的特殊情况
-
ASCII / UTF-8:一个字符就是一个字节 → 跟普通字符串一样,不涉及字节序。
-
UTF-16 / UTF-32:一个字符占 2 或 4 字节 → 又回到了“一个值多字节”,这时才出现 BOM(FE FF / FF FE) 去声明字节序。
4 把疑惑归纳成一句话
只有当『一个值 = 多个字节』且硬件需要决定“谁是高位谁是低位”时,才会有“字节序”的问题。
-
字符串里每个
char
本身就是最终字节 → 没有再组合的步骤 → 不受字节序影响 -
整数 / 浮点 / 宽字符 → 要把多字节拼成单个数 → 必须考虑字节序
🔑 快速检验口诀
-
看类型占几字节
-
1 字节 → 不用管字节序
-
1 字节 → 可能要管
-
-
看是不是“跨机器 / 写文件 / 发网络包”
-
是 → 需要统一字节序
-
否 → 在同一进程内直接用就行
-
希望这样分层解释后,“字符串为什么不会被倒序存”就清晰了!如果还想看实际打印内存的 demo,告诉我,我可以再给你补代码。