用
转
为十六进制字符串最稳妥
直接用
配合
和
/
,能控制位宽、补零、大小写,且不依赖 C++20。它处理符号位也直观:
是有符号类型,负数会按补码解释,但你通常想要的是其二进制表示的十六进制形式(即“字节级”输出),所以得先转成无符号整型再格式化。
必须先转成
,否则负数会输出带符号的十进制等效值(比如
变成
?不会——
对有符号负数仍按补码解释,但行为易混淆,显式转无符号更可靠)
用
通常是 16 位,即 4 个十六进制字符)
加
控制字母大小写;不加则默认小写
别用
处理
的十六进制转换
是 C++17 引入的无分配、高性能整数转字符串工具,但它只支持十进制、八进制、十六进制的 *无符号整型*,且没有内置补零或大小写控制。对
直接调用会编译失败(类型不匹配),强制转
后虽可工作,但你要自己管理缓冲区、手动补零、判断是否溢出——实际代码量和出错风险远超
。
不接受
,必须转成
或
才行
输出缓冲区至少要 5 字节(4 位 hex + 末尾
),少一分就
没补零逻辑,
会变成
,不是
大小写只能靠后续
,徒增开销
C++20
看似简洁,但要注意平台支持和符号处理
如果你确定用 C++20 且编译器支持(GCC 13+、Clang 15+、MSVC 19.30+),
是最接近“直觉写法”的选择。但它对负
的默认行为仍是按有符号解释,想得到固定宽度的无符号十六进制,还得显式转换 + 格式说明符。
写成
会触发隐式提升为
,负数输出长度不可控(如
→
)
正确写法是
Windows 上 MSVC 默认不启用
(需链接
或启用实验性开关)
嵌入式或旧构建环境基本不可用
手写查表法适合极致性能场景,但没必要为
这么干
真有每秒百万次以上转换需求,且 profiling 确认这里是瓶颈,才考虑用 256 字节查表 + 位运算拆高低字节。但对
来说,现代 CPU 上
的开销几乎可忽略,而手写逻辑极易出错:字节序搞反、大小端误判、符号扩展遗漏、边界值(如
)处理异常。
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
立即学习
“
C++免费学习笔记(深入)
”;
查表法本质是把
→ 2 字符映射预计算,再拼接高低字节结果
必须用
拆解,不能直接对
取地址强转(可能触发未定义行为)
维护成本高:换目标平台或加大小写支持就得重写表和拼接逻辑
绝大多数业务代码里,这是过早优化
真正容易被忽略的是:
的实际宽度不一定是 16 位(虽然几乎总是),
只保证 ≥ 1 字节。如果跨平台要求严格,应该用
替代
,并配合
转换——否则在极少数平台上,
可能不够,或者太多。
std::stringstreamshortstd::stringstreamstd::hexstd::setwstd::setfillshortunsigned short-1ffffffffstd::hexstd::setw(4) 确保输出 4 位(shortstd::uppercaseshort s = -42;
std::stringstream ss;
ss << std::hex << std::setw(4) << std::setfill('0') << static_cast(s);
std::string hex_str = ss.str(); // "ffc6"
std::to_charsshortstd::to_charsshortunsigned shortstd::stringstreamstd::to_charsshortunsigneduint16_t\0std::errc::value_too_large0x1"1""0001"std::transformstd::formatstd::formatshortstd::format("{:04x}", s)int-1"ffffffff"std::format("{:04x}", static_cast(s)) std::formatstdc++fsshortshortstd::stringstream0x8000uint8_tuint16_tshortshortsizeof(short)int16_tshortuint16_tsetw(4)