跳到主要内容

整数字面量

允许直接在表达式中使用整数类型的值。

语法

整数字面量形式如下:

1
十进制字面量整数后缀(可选)
2
八进制字面量整数后缀(可选)
3
十六进制字面量整数后缀(可选)
4
二进制字面量整数后缀(可选) (自 C++14 起)

其中:

  • 十进制字面量 是一个非零的十进制数字(1, 2, 3, 4, 5, 6, 7, 8, 9),后跟零个或多个十进制数字(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  • 八进制字面量 是数字零(0),后跟零个或多个八进制数字(0, 1, 2, 3, 4, 5, 6, 7)
  • 十六进制字面量 是字符序列 0x 或字符序列 0X,后跟一个或多个十六进制数字(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F)
  • 二进制字面量 是字符序列 0b 或字符序列 0B,后跟一个或多个二进制数字(0, 1)
  • 整数后缀,如果提供,可能包含以下一项或两项(如果两项都提供,可以按任何顺序出现)

    • 无符号后缀(字符 u 或字符 U
    • 以下之一

      • 长整型后缀(字符 l 或字符 L
      • 长长整型后缀(字符序列 ll 或字符序列 LL (自 C++11 起)
      • size后缀(字符 z 或字符 Z (自 C++23 起)
可选的单引号 ' 可以插入数字之间作为分隔符;在确定字面量值时会被忽略。 (自 C++14 起)

整数字面量(与其他任何字面量一样)是主表达式

解释

  1. 十进制整数字面量(基数 10)。
  2. 八进制整数字面量(基数 8)。
  3. 十六进制整数字面量(基数 16,字母 'a''f' 代表值(十进制)10 到 15)。
  4. 二进制整数字面量(基数 2)。整数字面量的第一个数字是最重要的。

示例。以下变量被初始化为相同的值

int d = 42;
int o = 052;
int x = 0x2a;
int X = 0X2A;
int b = 0b101010; // C++14

示例。以下变量也被初始化为相同的值

unsigned long long l1 = 18446744073709550592ull;       // C++11
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14
unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14

字面量的类型

整数字面量的类型是其值可以容纳的第一个类型,该类型列表取决于使用的数字基数和整数后缀

后缀十进制基数二进制、八进制或十六进制基数
(无后缀)
  • int
  • long int
  • long long int (自 C++11 起)
  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int (自 C++11 起)
  • unsigned long long int (自 C++11 起)
u 或 U
  • unsigned int
  • unsigned long int
  • unsigned long long int (自 C++11 起)
  • unsigned int
  • iunsigned long intnt
  • unsigned long long int (自 C++11 起)
l 或 L
  • long int
  • unsigned long int (直到 C++11)
  • long long int (自 C++11 起)
  • long int
  • unsigned long int
  • long long int (自 C++11 起)
  • unsigned long long int (自 C++11 起)
l/L 和 u/U 均有
  • unsigned long int
  • unsigned long long int (自 C++11 起)
  • unsigned long int
  • unsigned long long int (自 C++11 起)
ll 或 LL
  • long long int (自 C++11 起)
  • unsigned long int
  • unsigned long long int (自 C++11 起)
ll/LL 和 u/U 均有
  • unsigned long long int (自 C++11 起)
  • unsigned long long int (自 C++11 起)
z 或 Z
  • std::size_t 的有符号版本 (自 C++23 起)
  • std::size_t 的有符号版本 (自 C++23 起)
  • std::size_t (自 C++23 起)
z/Z 和 u/U 均有
  • std::size_t (自 C++23 起)
  • std::size_t (自 C++23 起)

如果整数字面量的值(不带 size 后缀 (自 C++23 起))过大,无法适应后缀/基数组合所允许的任何类型,并且编译器支持可以表示该字面量值的扩展整数类型(例如 __int128),则该字面量可以被赋予该扩展整数类型——否则程序将格式错误。

备注

整数字面量中的字母不区分大小写:0xDeAdBeEfU 和 0XdeadBEEFu 表示相同的数字 (一个例外是 长长整型后缀,只能是 llLL,绝不能是 lLLl)  (自 C++11 起)

没有负整数字面量。像 -1 这样的表达式会应用于字面量所代表的值,这可能涉及隐式类型转换。

在 C(C99 之前)中(但在 C++ 中不是),未加后缀的十进制值如果不适合 long int,则可以具有 unsigned long int 类型。

#if#elif 的控制表达式中使用时,所有有符号整数常量都表现为 std::intmax_t 类型,所有无符号整数常量都表现为 std::uintmax_t 类型 (自 C++11 起).

由于最大吞食,以 eE 结尾的十六进制整数字面量,后面紧跟 +- 运算符时,必须用空格或括号将它们与运算符分隔开

auto x = 0xE+2.0;   // error
auto y = 0xa+2.0; // OK
auto z = 0xE +2.0; // OK
auto q = (0xE)+2.0; // OK

否则,会形成一个无效的预处理数字标记,导致后续分析失败。

功能测试标准注释
__cpp_binary_literals201304L(C++14)二进制字面量
__cpp_size_t_suffix202011L(C++23)std::size_t 及其有符号版本的字面量后缀

示例

#include <cstddef>
#include <iostream>
#include <type_traits>

int main()
{
std::cout << 123 << '\n'
<< 0123 << '\n'
<< 0x123 << '\n'
<< 0b10 << '\n'
<< 12345678901234567890ull << '\n'
<< 12345678901234567890u << '\n'; // the type is unsigned long long
// even without a long long suffix

// std::cout << -9223372036854775808 << '\n'; // error: the value
// 9223372036854775808 cannot fit in signed long long, which is the
// biggest type allowed for unsuffixed decimal integer literal
std::cout << -9223372036854775808u << '\n'; // unary minus applied to unsigned
// value subtracts it from 2^64, this gives 9223372036854775808
std::cout << -9223372036854775807 - 1 << '\n'; // correct way to calculate
// the value -9223372036854775808

#if __cpp_size_t_suffix >= 202011L // C++23
static_assert(std::is_same_v<decltype(0UZ), std::size_t>);
static_assert(std::is_same_v<decltype(0Z), std::make_signed_t<std::size_t>>);
#endif
}
结果
123
83
291
2
12345678901234567890
12345678901234567890
9223372036854775808
-9223372036854775808

缺陷报告

以下改变行为的缺陷报告已追溯应用于先前发布的 C++ 标准。

DR应用于发布时的行为正确行为
CWG 2698(C++23)size 后缀的整数字面量可以有扩展整数类型如果太大,则格式错误

参考文献

  • C++23 标准 (ISO/IEC 14882:2023)
    • 5.13.2 Integer literals [lex.icon]
  • C++20 标准 (ISO/IEC 14882:2020)
    • 5.13.2 Integer literals [lex.icon]
  • C++17 标准 (ISO/IEC 14882:2017)
    • 5.13.2 Integer literals [lex.icon]
  • C++14 标准 (ISO/IEC 14882:2014)
    • 2.14.2 Integer literals [lex.icon]
  • C++11 标准 (ISO/IEC 14882:2011)
    • 2.14.2 Integer literals [lex.icon]
  • C++98 标准 (ISO/IEC 14882:1998)
    • 2.13.1 Integer literals [lex.icon]

整数字面量

允许直接在表达式中使用整数类型的值。

语法

整数字面量形式如下:

1
十进制字面量整数后缀(可选)
2
八进制字面量整数后缀(可选)
3
十六进制字面量整数后缀(可选)
4
二进制字面量整数后缀(可选) (自 C++14 起)

其中:

  • 十进制字面量 是一个非零的十进制数字(1, 2, 3, 4, 5, 6, 7, 8, 9),后跟零个或多个十进制数字(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  • 八进制字面量 是数字零(0),后跟零个或多个八进制数字(0, 1, 2, 3, 4, 5, 6, 7)
  • 十六进制字面量 是字符序列 0x 或字符序列 0X,后跟一个或多个十六进制数字(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F)
  • 二进制字面量 是字符序列 0b 或字符序列 0B,后跟一个或多个二进制数字(0, 1)
  • 整数后缀,如果提供,可能包含以下一项或两项(如果两项都提供,可以按任何顺序出现)

    • 无符号后缀(字符 u 或字符 U
    • 以下之一

      • 长整型后缀(字符 l 或字符 L
      • 长长整型后缀(字符序列 ll 或字符序列 LL (自 C++11 起)
      • size后缀(字符 z 或字符 Z (自 C++23 起)
可选的单引号 ' 可以插入数字之间作为分隔符;在确定字面量值时会被忽略。 (自 C++14 起)

整数字面量(与其他任何字面量一样)是主表达式

解释

  1. 十进制整数字面量(基数 10)。
  2. 八进制整数字面量(基数 8)。
  3. 十六进制整数字面量(基数 16,字母 'a''f' 代表值(十进制)10 到 15)。
  4. 二进制整数字面量(基数 2)。整数字面量的第一个数字是最重要的。

示例。以下变量被初始化为相同的值

int d = 42;
int o = 052;
int x = 0x2a;
int X = 0X2A;
int b = 0b101010; // C++14

示例。以下变量也被初始化为相同的值

unsigned long long l1 = 18446744073709550592ull;       // C++11
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14
unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14

字面量的类型

整数字面量的类型是其值可以容纳的第一个类型,该类型列表取决于使用的数字基数和整数后缀

后缀十进制基数二进制、八进制或十六进制基数
(无后缀)
  • int
  • long int
  • long long int (自 C++11 起)
  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int (自 C++11 起)
  • unsigned long long int (自 C++11 起)
u 或 U
  • unsigned int
  • unsigned long int
  • unsigned long long int (自 C++11 起)
  • unsigned int
  • iunsigned long intnt
  • unsigned long long int (自 C++11 起)
l 或 L
  • long int
  • unsigned long int (直到 C++11)
  • long long int (自 C++11 起)
  • long int
  • unsigned long int
  • long long int (自 C++11 起)
  • unsigned long long int (自 C++11 起)
l/L 和 u/U 均有
  • unsigned long int
  • unsigned long long int (自 C++11 起)
  • unsigned long int
  • unsigned long long int (自 C++11 起)
ll 或 LL
  • long long int (自 C++11 起)
  • unsigned long int
  • unsigned long long int (自 C++11 起)
ll/LL 和 u/U 均有
  • unsigned long long int (自 C++11 起)
  • unsigned long long int (自 C++11 起)
z 或 Z
  • std::size_t 的有符号版本 (自 C++23 起)
  • std::size_t 的有符号版本 (自 C++23 起)
  • std::size_t (自 C++23 起)
z/Z 和 u/U 均有
  • std::size_t (自 C++23 起)
  • std::size_t (自 C++23 起)

如果整数字面量的值(不带 size 后缀 (自 C++23 起))过大,无法适应后缀/基数组合所允许的任何类型,并且编译器支持可以表示该字面量值的扩展整数类型(例如 __int128),则该字面量可以被赋予该扩展整数类型——否则程序将格式错误。

备注

整数字面量中的字母不区分大小写:0xDeAdBeEfU 和 0XdeadBEEFu 表示相同的数字 (一个例外是 长长整型后缀,只能是 llLL,绝不能是 lLLl)  (自 C++11 起)

没有负整数字面量。像 -1 这样的表达式会应用于字面量所代表的值,这可能涉及隐式类型转换。

在 C(C99 之前)中(但在 C++ 中不是),未加后缀的十进制值如果不适合 long int,则可以具有 unsigned long int 类型。

#if#elif 的控制表达式中使用时,所有有符号整数常量都表现为 std::intmax_t 类型,所有无符号整数常量都表现为 std::uintmax_t 类型 (自 C++11 起).

由于最大吞食,以 eE 结尾的十六进制整数字面量,后面紧跟 +- 运算符时,必须用空格或括号将它们与运算符分隔开

auto x = 0xE+2.0;   // error
auto y = 0xa+2.0; // OK
auto z = 0xE +2.0; // OK
auto q = (0xE)+2.0; // OK

否则,会形成一个无效的预处理数字标记,导致后续分析失败。

功能测试标准注释
__cpp_binary_literals201304L(C++14)二进制字面量
__cpp_size_t_suffix202011L(C++23)std::size_t 及其有符号版本的字面量后缀

示例

#include <cstddef>
#include <iostream>
#include <type_traits>

int main()
{
std::cout << 123 << '\n'
<< 0123 << '\n'
<< 0x123 << '\n'
<< 0b10 << '\n'
<< 12345678901234567890ull << '\n'
<< 12345678901234567890u << '\n'; // the type is unsigned long long
// even without a long long suffix

// std::cout << -9223372036854775808 << '\n'; // error: the value
// 9223372036854775808 cannot fit in signed long long, which is the
// biggest type allowed for unsuffixed decimal integer literal
std::cout << -9223372036854775808u << '\n'; // unary minus applied to unsigned
// value subtracts it from 2^64, this gives 9223372036854775808
std::cout << -9223372036854775807 - 1 << '\n'; // correct way to calculate
// the value -9223372036854775808

#if __cpp_size_t_suffix >= 202011L // C++23
static_assert(std::is_same_v<decltype(0UZ), std::size_t>);
static_assert(std::is_same_v<decltype(0Z), std::make_signed_t<std::size_t>>);
#endif
}
结果
123
83
291
2
12345678901234567890
12345678901234567890
9223372036854775808
-9223372036854775808

缺陷报告

以下改变行为的缺陷报告已追溯应用于先前发布的 C++ 标准。

DR应用于发布时的行为正确行为
CWG 2698(C++23)size 后缀的整数字面量可以有扩展整数类型如果太大,则格式错误

参考文献

  • C++23 标准 (ISO/IEC 14882:2023)
    • 5.13.2 Integer literals [lex.icon]
  • C++20 标准 (ISO/IEC 14882:2020)
    • 5.13.2 Integer literals [lex.icon]
  • C++17 标准 (ISO/IEC 14882:2017)
    • 5.13.2 Integer literals [lex.icon]
  • C++14 标准 (ISO/IEC 14882:2014)
    • 2.14.2 Integer literals [lex.icon]
  • C++11 标准 (ISO/IEC 14882:2011)
    • 2.14.2 Integer literals [lex.icon]
  • C++98 标准 (ISO/IEC 14882:1998)
    • 2.13.1 Integer literals [lex.icon]