char固定1字节,short至少2字节;char符号性实现定义,short默认有符号;混用指针易引发对齐、端序和未定义行为问题。

short 和 char 内存大小根本不一样
别被“char 也能当整数用”带偏——char 绝大多数平台下占 1 字节(8 位),而 short 至少 16 位,通常是 <strong>2 字节</strong>。所谓“两者都占 16 位”的说法是错的,那混淆了 <code>unsigned short 和某种非标准 char 扩展(比如某些嵌入式环境的 __char16_t),在标准 C++ 中不成立。
-
char:固定 1 字节,sizeof(char)恒为 1(这是 C++ 标准强制保证的) -
short:sizeof(short)≥ 2,常见为 2;不能假设它等于sizeof(char) - 混用指针时尤其危险:
short*加 1 跳 2 字节,char*加 1 只跳 1 字节——直接 reinterpret_cast 可能读错字节边界
数值范围和符号性差异直接影响行为
char 的符号性是实现定义的:它可能是 signed char(-128 ~ 127),也可能是 unsigned char(0 ~ 255),取决于编译器和平台;而 short 默认是 signed short(-32768 ~ 32767),unsigned short 则是(0 ~ 65535)。
- 做算术运算时,
char常被提升为int,但溢出行为取决于其实际符号性——char c = 127; c++;在 signed-char 平台结果是 -128,在 unsigned-char 平台是 128,不可移植 -
short溢出是未定义行为(UB),编译器可能优化掉你认为“理所当然”的逻辑,比如short s = 32767; s++;后再比较,结果不可靠 - 如果需要明确无符号 8 位整数,就用
uint8_t(来自<cstdint></cstdint>),别依赖char;需要明确有符号 16 位,就用int16_t
什么时候该用 short,什么时候该用 char
选类型不是看“哪个更短”,而是看语义和上下文。
- 存单个 ASCII 字符、做字符串操作、做字节级 I/O(如
read()/write()缓冲区)→ 用char或unsigned char(尤其涉及二进制数据时,unsigned char更安全) - 存小范围整数(如温度、状态码、索引偏移),且确认值不会超 ±32767 → 可考虑
short,但现代 CPU 对int运算往往更快,short主要省内存(比如百万级数组) - 跨平台序列化或网络协议字段 → 必须用定宽类型:
int16_t/uint8_t,绝不用裸short或char - 函数参数中传单字节标志?用
std::byte(C++17)或uint8_t,比char语义清晰,避免与字符逻辑混淆
reinterpret_cast 和 reinterpret_cast 的坑
这是最常出问题的地方:把一块内存一会儿当 char* 读,一会儿当 short* 解释,稍不注意就踩内存对齐或端序雷。
立即学习“C++免费学习笔记(深入)”;
-
short通常要求 2 字节对齐;若从char*强转short*,而原地址是奇数(如&buf[1]),在 ARM 等严格对齐平台会触发硬件异常 - 即使对齐安全,
*(short*)buf的值还取决于机器字节序(小端/大端)——同一段字节数组,char buf[] = {0x01, 0x02};,在 x86 上*(short*)buf是 0x0201,不是 0x0102 - 正确做法:用
memcpy拆装,或用std::bit_cast(C++20),避免裸指针重解释
真正麻烦的从来不是“它们差在哪”,而是你忘了 char 的符号性不确定、short 的大小不保证、以及指针重解释时对齐和端序全得自己兜底。










