书籍:《ISO/IEC 14882 2014》
说明:以上内容大部分来自腾讯元宝。
如何理解以下内容:
1
An integer literal is a sequence of digits that has no period or exponent part, with optional separating single quotes that are ignored when determining its value. An integer literal may have a prefix that specifies its base and a suffix that specifies its type. The lexically first digit of the sequence of digits is the most significant. A
decimal
integer literal (base ten) begins with a digit other than
0 and consists of a sequence of decimal digits. An
octal
integer literal (base eight) begins with the digit
0 and consists of a sequence of octal digits.
22
A
hexadecimal
integer literal (base sixteen) begins with
0x
or
0X and consists of a sequence of hexadecimal digits, which include the decimal digits and the letters
a
through
f
and
A
through
F with decimal values ten through fifteen. A
binary
integer literal (base two) begins with
0b
or
0B and consists of a sequence of binary digits. [
Example:
The number twelve can be written
12
,
014
,
0XC
, or
0b1100. The literals
1048576
,
1’048’576
,
0X100000
,
0x10’0000
, and
0’004’000’000
all have the same value.
— end
example
]
一、整数字面量的基本结构
整数字面量的定义分为三个核心部分:
- 数字序列:由数字字符组成,无小数点或指数部分。
- 分隔符(可选):单引号
'
用于提高可读性,不影响数值(C++14引入)。 - 前缀(可选):指定进制(如
0x
表示十六进制)。 - 后缀(可选):指定类型(如
u
表示无符号整数)。
示例:
int a = 12; // 十进制
int b = 014; // 八进制(等价于十进制12)
int c = 0XC; // 十六进制(等价于十进制12)
int d = 0b1100; // 二进制(等价于十进制12)
二、进制规则详解
1. 十进制(Decimal)
- 前缀:无。
- 数字范围:
1-9
开头,后跟任意数字(可含分隔符)。 - 示例:
int x = 1'000'000; // 分隔符提高可读性,等价于1000000[1,6](@ref)
2. 八进制(Octal)
- 前缀:
0
(零)。 - 数字范围:
0-7
。 - 示例:
int y = 0377; // 八进制最大值(等价于十进制255)
3. 十六进制(Hexadecimal)
- 前缀:
0x
或0X
。 - 数字范围:
0-9
、a-f
(或A-F
)。 - 示例:
int z = 0XFF; // 十六进制最大值(等价于十进制255)
4. 二进制(Binary)
- 前缀:
0b
或0B
(C++14引入)。 - 数字范围:
0-1
。 - 示例:
int w = 0b1111'1111; // 二进制最大值(等价于十进制255)
三、类型后缀的作用
后缀用于显式指定整数字面量的类型,规则如下:
后缀 | 类型 | 示例 |
---|---|---|
u | unsigned int | 42u |
l | long | 123l |
ll | long long | 123ll |
ul | unsigned long | 123ul |
ull | unsigned long long | 123ull |
规则:
- 后缀顺序不影响类型(如
LU
与UL
等价)。 - 无后缀时,类型由数值大小决定(如
42
默认为int
)。
四、示例解析
示例1:相同值的多种表示
int a = 1048576; // 十进制
int b = 1'048'576; // 十进制(分隔符)
int c = 0X100000; // 十六进制(0x100000 = 1,048,576)
int d = 0x10'0000; // 十六进制(分隔符)
int e = 0'004'000'000; // 十进制(分隔符,等价于4,000,000)
- 结论:所有字面量均等于十进制
1,048,576
。
示例2:进制转换
int f = 014; // 八进制14 → 十进制12
int g = 0XC; // 十六进制C → 十进制12
int h = 0b1100; // 二进制1100 → 十进制12
五、关键注意事项
- 分隔符合法性:
- 单引号
'
仅用于分隔数字,不可出现在数字序列首尾或连续使用(如'123'
非法)。
- 单引号
- 前缀与后缀的顺序:
- 前缀必须位于数字序列前,后缀必须位于末尾(如
0x12u
合法,u0x12
非法)。
- 前缀必须位于数字序列前,后缀必须位于末尾(如
- 非法字符检测:
- 八进制中若包含
8
或9
(如0389
)会导致编译错误。
- 八进制中若包含
六、实际应用建议
- 明确类型:使用后缀避免隐式类型转换(如
42u
比42
更安全)。 - 可读性优化:对大数值使用分隔符(如
1'000'000
)。 - 进制选择:二进制用于位操作,十六进制用于内存地址或颜色值,十进制用于通用场景。
通过理解这些规则,可以更精准地控制整数字面量的类型和值,避免因隐式转换或语法错误导致的程序缺陷。