使用 std::hex 需配合 std::showbase 加 0x 前缀、std::uppercase 控制大小写、std::setw 与 std::setfill 补零;负数按补码输出,指针须转 uintptr_t;推荐封装函数统一格式。

直接用 std::hex 配合 std::cout 即可输出十六进制,但默认不补零、不带 0x 前缀、大小写和字段宽度需手动控制——这些恰恰是实际开发中最常出错的地方。
怎么让 cout 输出带 0x 前缀的十六进制
仅用 std::hex 不会自动加 0x,必须搭配 std::showbase:
#includeint main() { std::cout << std::hex << std::showbase << 255 << '\n'; // 输出: 0xff }
-
std::showbase对std::hex生效时加0x,对std::oct加0,对std::dec无影响 - 前缀大小写由后续是否启用
std::uppercase决定(见下一条) - 一旦设置
std::showbase,它会持续生效,直到被std::noshowbase关闭
怎么控制字母大小写和补零位数
十六进制字母默认小写,数字不自动补零;需分别用 std::uppercase 和 std::setw+std::setfill:
#includestd::cout << std::hex << std::uppercase << std::showbase << std::setw(4) << std::setfill('0') << 255 << '\n'; // 输出: 0X00FF
-
std::uppercase影响前缀(0X)和字母(A-F),不是只改字母 -
std::setw只对下一个输出项生效,必须和std::setfill配合才能补零 - 如果要固定 8 位(如打印指针或寄存器值),常用
std::setw(8)
为什么 int 类型负数输出结果看起来“不对”
因为 std::hex 直接按二进制补码解释整数,不会做符号扩展或转换处理:
立即学习“C++免费学习笔记(深入)”;
std::cout << std::hex << -1 << '\n'; // 在 32 位系统上通常输出: ffffffff
- 这不是 bug,而是底层位模式的直接呈现。-1 的 32 位补码就是全 1
- 若想输出带符号的十六进制(比如显示为
-0x1),C++ 标准流不支持,得自己判断正负后手动拼接 - 更安全的做法:对负数先转成无符号类型再输出,例如
static_cast(x)
输出指针地址时的常见陷阱
直接用 std::hex 输出指针会报错或行为未定义,必须先转成 uintptr_t:
#includeint x = 42; std::cout << std::hex << std::showbase << reinterpret_cast (&x) << '\n';
- 不能对
void*直接用+std::hex,某些编译器会调用重载的指针输出(即显示地址但不走 hex 流控) -
uintptr_t是能容纳指针的无符号整数类型,来自 - 若需统一格式(如 16 进制小写+0x+16 位宽),建议封装成函数,避免每次重复写一长串 manipulator
真正麻烦的从来不是“怎么打出十六进制”,而是“怎么让每种场景下的输出都稳定、可读、符合协议”——尤其是混合调试日志、内存 dump 和协议字段打印时,std::hex 的状态残留、setw 作用域、有符号/无符号混用,最容易在深夜排查问题时悄悄翻车。










