有符号 short int 的取值上限是 32767,下限是 -32768,由 C++ 标准保证最小 16 位范围,实际实现几乎均为 exactly 16 位有符号整数,SHRT_MAX 恒为 32767。

short int 的取值上限到底是多少?
有符号 short int(即默认的 short)在几乎所有现代平台(x86/x64、Linux/macOS/Windows)上的取值上限是 32767,下限是 -32768。这不是“大概”,而是由 C++ 标准要求的最小保证范围(至少 16 位),实际实现几乎全为 exactly 16 位有符号整数。
常见误解是认为“short 就是 2 字节,所以最大是 65535”——错,那是 unsigned short 的上限。只要没写 unsigned,就默认带符号,最高位是符号位。
-
SHRT_MAX宏定义在<climits>中,值恒为32767;用std::numeric_limits<short>::max()也能拿到同一结果 - 溢出行为是未定义的(C++11 起),但实践中多数编译器做模运算:比如
32767 + 1→-32768,别依赖这个 - 不要靠 sizeof(short) == 2 来断言范围——理论上它可能更大(如某些嵌入式平台),但上限仍由
SHRT_MAX决定
什么时候必须用 unsigned short?
当你明确只需要非负数,且数据天然在 0–65535 区间内时,比如:端口号(0–65535)、UTF-16 code unit、小尺寸图像像素灰度(若用 16-bit 表示)、计数器上限已知且 ≤65535。
- 用
unsigned short后,USHRT_MAX是65535,比有符号多一倍正数空间 - 混合运算要小心:
short a = -1; unsigned short b = 1; auto c = a + b;→c是unsigned int类型,结果变成大正数(4294967295),不是 0 - 函数接口中若接收
unsigned short,传入负数会静默截断,不报错也不警告(除非开-Wconversion)
怎么安全地检查 short 是否会溢出?
不能靠运行时“加完再判断是否变负”——这是未定义行为,优化器可能直接删掉判断逻辑。正确做法是加法前做范围预检。
立即学习“C++免费学习笔记(深入)”;
#include <climits>
bool would_overflow_short(short a, short b) {
if (b > 0) return a > SHRT_MAX - b;
if (b < 0) return a < SHRT_MIN - b;
return false;
}
- 别用
a + b < 0这类后验判断——UB,Clang/GCC -O2 下可能失效 - 使用
std::add_overflow(C++23)或第三方库如absl::int16_t可简化,但需确认编译器支持 - 如果只是临时计算,优先升到
int:短整型参与算术运算时本就会提升,直接用int中间变量最省心
为什么 sizeof(short) 总是 2,但还是建议少用?
因为它的“小”是假象:现代 CPU 对 short 的加载/存储常需额外指令对齐或零扩展,性能未必比 int 好;而内存节省仅在大量数组场景才明显(比如百万级 short 数组 vs int)。
- 结构体里混用
short和char可能因对齐反而更占空间(如struct {char a; short b;}往往占 4 字节而非 3) - 跨平台序列化时,
short的字节序和大小虽稳定,但不如int16_t明确——后者来自<cstdint>,语义清晰无歧义 - 调试器或日志打印时,
short常被自动转成int显示,容易让人忽略它的真实边界
真正关键的不是“short 能存多大”,而是你是否需要它那精确的 16 位语义——否则,老实用 int16_t 或 int 更稳妥。










