unsigned short 取值范围为0–65535、通常占2字节,但跨平台不保证;应使用%hu格式化、优先选uint16_t保宽度,隐式提升和截断易引发隐蔽错误。

unsigned short 的取值范围和内存占用
它在标准 C++ 里是至少 16 位的无符号整数类型,实际通常是 uint16_t 的别名(但不等价),典型取值范围是 0 到 65535。大小由编译器和平台决定,sizeof(unsigned short) 在绝大多数现代系统上返回 2,但不能硬编码依赖这点。
常见错误现象:把 unsigned short 当作“一定占 2 字节”来跨平台序列化,结果在某些嵌入式平台或旧编译器上出错。
- 用
std::numeric_limits<unsigned short>::max()</unsigned>替代魔法数字 65535,更可读也更安全 - 如果必须保证 16 位宽度,优先选
uint16_t(需#include <cstdint></cstdint>) - 函数参数传递时,小整型常被提升为
int,所以void f(unsigned short x)和void f(int x)可能意外重载冲突
赋值和隐式转换容易踩的坑
它对负数、超范围值的处理非常“安静”——不报错,只截断。比如 unsigned short x = -1; 得到 65535;unsigned short y = 70000; 得到 4464(70000 % 65536)。
使用场景:适合明确控制在 0–65535 内的计数器、状态码、小尺寸缓存索引等,不适合做通用算术中间变量。
立即学习“C++免费学习笔记(深入)”;
- 从有符号类型赋值前,先检查是否 >= 0 且 std::numeric_limits
::max() - 读取用户输入或文件数据时,别直接
cin >> x(x 是unsigned short),否则输入负数会触发流失败状态 - 和
int混合运算时,整个表达式会被提升为int,可能掩盖溢出意图(比如unsigned short a = 65535, b = 1; auto c = a + b;,c 是int值 65536,不是回绕的 0)
printf / scanf 中怎么正确格式化
printf 和 scanf 不认识 unsigned short,必须用 %hu(h 表示 short,u 表示 unsigned)。用 %u 或 %d 会导致未定义行为,常见表现是打印乱码或崩溃。
示例:
unsigned short val = 42;
printf("val = %hu\n", val); // ✅ 正确
printf("val = %u\n", val); // ❌ 未定义行为
- C++ 流(
std::cout)没这个问题,直接用就行 - 如果用
scanf,注意传地址:scanf("%hu", &val);,漏掉&是常见段错误原因 - 在格式化字符串中混用
%hu和%u容易遗漏,建议统一用 C++ 流避免这类问题
和 vector 配合时的性能注意点
连续存储 unsigned short 是紧凑的,但 CPU 通常按字(word)对齐访问,某些架构下非对齐读写会有性能惩罚。不过现代 x86/x64 一般不明显,真正影响大的是缓存行利用率。
使用场景:图像像素(如灰度图)、音频采样、网络协议字段等需要节省空间的批量数据。
- 避免频繁单个元素访问,尽量用指针或迭代器批量处理(比如用
memcpy复制一段) - 不要为了“省内存”而把
vector<int></int>强转成vector<unsigned short></unsigned>—— 类型不兼容,reinterpret_cast极易出错 - 如果要做大量数学运算(如累加、滤波),考虑临时转成
int计算,最后再存回,避免反复截断










