short是有符号类型,取值范围-32768~32767;unsigned short是无符号类型,取值范围0~65535;二者虽同占2字节,但符号位处理、溢出行为、比较逻辑及隐式转换规则均不同。

short 是有符号的,unsigned short 是无符号的
这是最根本的区别:两者底层都占 2 字节(典型实现),但解释方式完全不同。short 把最高位当符号位,取值范围是 -32768 到 32767;unsigned short 没有符号位,全部 16 位都表示数值,范围是 0 到 65535。别想当然认为“只是正负号不同”——溢出行为、比较逻辑、隐式转换全都不一样。
混用时隐式转换会悄悄改变语义
当你把 short 和 unsigned short 放进同一个表达式(比如相加或比较),C++ 会按整型提升规则转成 int 或 unsigned int,但具体转成谁,取决于值和平台。容易踩的坑:
- 如果
short x = -1;和unsigned short y = 1;比较x ,<code>x先提升为int(-1),y提升为unsigned int(1),但比较前-1会被重解释为巨大的正数(4294967295),结果false - 在函数重载中,
void f(short)和void f(unsigned short)是两个完全不同的函数,传0可能调不到你预期的那个 - printf 里错用格式符:
printf("%d", us)(us是unsigned short)是未定义行为,该用%hu
为什么不用 int 而选 short?真有必要才用
short 和 unsigned short 的存在意义,几乎只在内存敏感场景:比如处理大量二维图像像素(每个像素用 unsigned short 存 0–65535 灰度值)、嵌入式寄存器映射、网络协议字段对齐。普通业务逻辑里硬写 short,反而容易因范围小导致溢出,还失去跨平台可移植性(short 最小保证是 ≥16 位,但某些 DSP 平台可能是 32 位)。
- 数组大小差一倍:
short[1000]占 2000 字节,int[1000]在多数平台占 4000 字节 - 现代 CPU 对
int运算通常更快,short可能触发额外的截断指令 - STL 容器(如
vector<short></short>)不比vector<int></int>更省内存——因为对齐和分配器开销可能抵消掉那点字节
判断变量类型时,sizeof 不等于一切
sizeof(short) 和 sizeof(unsigned short) 总是相等,但这不代表它们可互换。真正关键的是 std::numeric_limits:
立即学习“C++免费学习笔记(深入)”;
static_assert(std::numeric_limits<short>::is_signed, "short must be signed"); static_assert(!std::numeric_limits<unsigned short>::is_signed, "unsigned short must not be signed"); static_assert(std::numeric_limits<short>::min() == -32768, ""); static_assert(std::numeric_limits<unsigned short>::max() == 65535, "");
靠 sizeof 或 “看起来像正数” 来推断类型,迟早翻车。尤其在模板元编程或 SFINAE 中,std::is_same_v<T, unsigned short> 和 std::is_unsigned_v<T> 行为也不同——前者严格匹配类型,后者对任何无符号整型都返回 true。
边界值、隐式提升、类型擦除——这些地方没一行注释都可能埋雷。别信直觉,信 numeric_limits 和实际运行时输出。










