c++整数常量通过前缀(0x十六进制、0八进制、无前缀十进制、0b二进制)和后缀(u、l、ll等)确定进制与类型;08、09非法因八进制不含8、9;auto推导依赖字面量类型,存在跨平台陷阱;c++14支持二进制和单引号分隔符提升可读性。

整数常量的进制与后缀组合规则
C++里整数常量不是随便写个数字就完事,编译器靠前缀和后缀来判断类型和进制。没写对,轻则类型推导出错(比如 123 被当 int,但你其实想用 long long),重则字面量非法(比如 08 直接报错:八进制不能有 8)。
必须记住三类前缀:0x 或 0X 表十六进制,0 开头是八进制(注意:不是 0o!C++ 不支持这种 Python 风格),十进制无前缀;后缀可选,用来指定宽度或符号性,比如 U(unsigned)、L(long)、LL(long long),大小写不敏感但惯例用大写。
-
100→ 十进制int(或能容纳它的最小有符号类型) -
0144→ 八进制,等价于十进制100,类型仍是int -
0x64、0X64→ 十六进制,同样等于100 -
10000000000LL→ 十进制,强制为long long,避免在 32 位平台溢出 -
0xFFFFFFFFU→ 十六进制无符号整数,确保高位不会被解释成负数
为什么 08 和 09 编译不过
因为以 0 开头的字面量被严格当作八进制处理,而八进制只有 0–7。所以 08 中的 8 是非法数字,Clang/GCC 都会报类似 invalid digit '8' in octal constant 的错误。
这不是警告,是硬性语法错误。哪怕你只是想写“零后跟八”,也得写成 8(十进制)或 0x8(十六进制)。别指望编译器自动 fallback——C++ 字面量解析是确定性的,不猜意图。
- 错误写法:
08、09、019 - 正确替代:
8、9、19(十进制),或0x8、0x9、0x13(十六进制) - 历史包袱:这个
0前缀源自 C,至今保留,但容易误踩,现代代码建议尽量显式用0x表十六进制,十进制就老老实实不加前缀
auto 推导时整数常量的隐含类型陷阱
用 auto 声明变量时,整数常量的字面量类型直接影响推导结果,而且它不总是你直觉里的“最自然类型”。比如 auto x = 1; 推出 int,但 auto y = 10000000000; 在 32 位系统上可能推成 long long(因为 int 装不下),而 auto z = 0U; 就一定是 unsigned int。
更隐蔽的是混合运算:如果参与算术的两个操作数类型不同(比如 int 和 unsigned),会发生整型提升和转换,可能产生静默截断或符号翻转。所以不要依赖 auto 来“省事”,尤其在涉及边界值或跨平台时。
-
auto a = 2147483647;→ 通常是int(刚好是 32 位INT_MAX) -
auto b = 2147483648;→ 必为long long或unsigned int(取决于编译器和平台) -
auto c = 0xFFU + 1;→ 结果是unsigned int,不会变成int,即使值很小
C++14 起支持的二进制和单引号分隔写法
C++14 加了两个实用特性:二进制字面量用 0b 或 0B 前缀,以及允许在任意整数字面量中用单引号 ' 作千位分隔符(纯语法糖,不影响值和类型)。
它们不改变底层语义,但极大提升可读性,尤其对位掩码、硬件寄存器配置这类场景。注意单引号只能出现在数字中间,不能开头、结尾或连续出现,否则编译失败。
- 二进制:
0b1010(=10),0B1111'1111(=255) - 分隔符:
1'000'000(百万),0xFF'FF'00'00(比0xFFFF0000更易定位字节边界) - 错误用法:
'123'、123'、12''34、0b'1010(引号不能紧贴前缀)
这些写法在嵌入式或协议解析代码里很常见,但要注意旧编译器(如 GCC
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











