命名空间
变体
操作

字符字面量

来自 cppreference.com
< cpp‎ | 语言
 
 
C++ 语言
表达式
替代表示
字面量
布尔值 - 整数 - 浮点型
字符 - 字符串 - nullptr (C++11)
用户定义的 (C++11)
实用程序
属性 (C++11)
类型
typedef 声明
类型别名声明 (C++11)
强制转换
内存分配
特定于类的函数属性
explicit (C++11)
static

特殊成员函数
模板
其他
 
 

内容

[编辑] 语法

'c-char ' (1)
u8'c-char ' (2) (自 C++17 起)
u'c-char ' (3) (自 C++11 起)
U'c-char ' (4) (自 C++11 起)
L'c-char ' (5)
'c-char-sequence ' (6)
L'c-char-sequence ' (7) (直到 C++23)
c-char - 要么
  • 一个 basic-c-char
  • 一个转义序列,如 转义序列 中所定义
  • 一个通用字符名,如 转义序列 中所定义
basic-c-char - 来自 基本源字符集(直到 C++23)翻译字符集(自 C++23 起) 的字符,除了单引号 '、反斜杠 \ 或换行符
c-char-sequence - 两个或更多个 c-chars

[编辑] 解释

1) 普通字符字面量,例如 'a''\n''\13'。此类字面量的类型为 char,其值等于 c-char执行字符集 中的表示形式(直到 C++23)来自 普通字面量编码 的相应代码点(自 C++23 起)
2) UTF-8 字符字面量,例如 u8'a'。这种字面量类型为 char(在 C++20 之前)char8_t(从 C++20 开始),其值等于 ISO/IEC 10646c-char 的码点值,前提是该码点值可以用单个 UTF-8 码元表示(即,c-char 在 0x0-0x7F 范围内,包括边界值)。
3) UTF-16 字符字面量,例如 u'猫',但不是 u'🍌' (u'\U0001f34c')。这种字面量类型为 char16_t,其值等于 ISO/IEC 10646c-char 的码点值,前提是该码点值可以用单个 UTF-16 码元表示(即,c-char 在 0x0-0xFFFF 范围内,包括边界值)。
4) UTF-32 字符字面量,例如 U'猫'U'🍌'。这种字面量类型为 char32_t,其值等于 ISO/IEC 10646c-char 的码点值。
5) 宽字符字面量,例如 L'β'L'猫'。这种字面量类型为 wchar_t,其值等于 执行宽字符集中的 c-char 的值(在 C++23 之前)宽字面量编码中对应的码点(从 C++23 开始)
6) 普通多字符字面量(在 C++23 之前)多字符字面量(从 C++23 开始),例如 'AB',是条件支持的,类型为 int,其值为实现定义的。
7) 宽多字符字面量,例如 L'AB',是条件支持的,类型为 wchar_t,其值为实现定义的。

[edit] 不可编码字符

1-5) 鉴于 c-char 不是数字转义序列(见下文),如果 c-char 在字面量的关联字符编码中不可表示,或者不能在该编码中作为单个码元进行编码(例如,在 Windows 上,其中 wchar_t 为 16 位,非 BMP 值),程序将形成错误。
6) 如果 c-char-sequence 中的任何 c-char 无法在 普通字面量编码 中作为单个码元进行编码,程序将形成错误。
7) 如果 c-char-sequence 中的任何 c-char 无法在 宽字面量编码 中作为单个码元进行编码,程序将形成错误。
(直到 C++23)

[edit] 数字转义序列

数字(八进制和十六进制)转义序列可用于指定字符的值。

如果字符字面量只包含一个数字转义序列,并且转义序列指定的数值可以用其类型对应的无符号类型表示,则字符字面量将与指定的数值具有相同的值(可能在转换为字符类型后)。

UTF-N 字符字面量可以具有其类型所能表示的任何值。如果该值不对应于有效的 Unicode 码点,或者其对应的码点无法在 UTF-N 中作为单个码元表示,仍然可以通过数字转义序列来指定该值。例如,u8'\xff' 是格式良好的,等于 char8_t(0xFF)

(从 C++23 开始)


如果普通或宽字符字面量中使用的数字转义序列指定的数值无法用 charwchar_t 分别表示,则字符字面量的值为实现定义的。

(直到 C++23)

如果在具有一个 c-char 的普通或宽字符字面量中使用的数字转义序列指定的数值可以用 charwchar_t 对应的底层类型的无符号版本分别表示,则字面量的值为该无符号整型类型的整型值,并且指定的值将转换为字面量的类型。否则,程序将形成错误。

(从 C++23 开始)


如果在 UTF-N 字符字面量中使用的数字转义序列指定的数值无法用相应的 charN_t 表示,字符字面量的值为实现定义的(在 C++17 之前)程序将形成错误(从 C++17 开始)

(自 C++11 起)

[edit] 注释

多字符字面量是 C 从 B 编程语言继承来的。尽管 C 或 C++ 标准中没有明确规定,但大多数编译器(MSVC 是一个显著的例外)都实现了 B 中规定的多字符字面量:字面量中每个 char 的值都会初始化结果整型的连续字节,按大端零填充右对齐顺序,例如,'\1' 的值为 0x00000001,而 '\1\2\3\4' 的值为 0x01020304

在 C 中,'a''\n' 这样的字符常量类型为 int,而不是 char

[edit] 示例

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string_view>
 
template<typename CharT>
void dump(std::string_view s, const CharT c)
{
    const uint8_t* data{reinterpret_cast<const uint8_t*>(&c)};
 
    std::cout << s << " \t" << std::hex
              << std::uppercase << std::setfill('0');
 
    for (auto i{0U}; i != sizeof(CharT); ++i)
        std::cout << std::setw(2) << static_cast<unsigned>(data[i]) << ' ';
 
    std::cout << '\n';
}
 
void print(std::string_view str = "") { std::cout << str << '\n'; }
 
int main()
{
    print("Ordinary character literals:");
    char c1 = 'a'; dump("'a'", c1);
    char c2 = '\x2a'; dump("'*'", c2);
 
    print("\n" "Ordinary multi-character literals:");
    int mc1 = 'ab'; dump("'ab'", mc1);       // implementation-defined
    int mc2 = 'abc'; dump("'abc'", mc2);     // implementation-defined
 
    print("\n" "UTF-8 character literals:");
    char8_t C1 = u8'a'; dump("u8'a'", C1);
//  char8_t C2 = u8'¢'; dump("u8'¢'", C2);   // error: ¢ maps to two UTF-8 code units
//  char8_t C3 = u8'猫'; dump("u8'猫'", C3); // error: 猫 maps to three UTF-8 code units
//  char8_t C4 = u8'🍌'; dump("u8'🍌'", C4); // error: 🍌 maps to four UTF-8 code units
 
    print("\n" "UTF-16 character literals:");
    char16_t uc1 = u'a'; dump("u'a'", uc1);
    char16_t uc2 = u'¢'; dump("u'¢'", uc2);
    char16_t uc3 = u'猫'; dump("u'猫'", uc3);
//  char16_t uc4 = u'🍌'; dump("u'🍌'", uc4); // error: 🍌 maps to two UTF-16 code units
 
    print("\n" "UTF-32 character literals:");
    char32_t Uc1 = U'a'; dump("U'a'", Uc1);
    char32_t Uc2 = U'¢'; dump("U'¢'", Uc2);
    char32_t Uc3 = U'猫'; dump("U'猫'", Uc3);
    char32_t Uc4 = U'🍌'; dump("U'🍌'", Uc4);
 
    print("\n" "Wide character literals:");
    wchar_t wc1 = L'a'; dump("L'a'", wc1);
    wchar_t wc2 = L'¢'; dump("L'¢'", wc2);
    wchar_t wc3 = L'猫'; dump("L'猫'", wc3);
    wchar_t wc4 = L'🍌'; dump("L'🍌'", wc4);  // unsupported on Windows since C++23
}

可能的输出

Ordinary character literals:
'a' 	61 
'*' 	2A 
 
Ordinary multi-character literals:
'ab' 	62 61 00 00 
'abc' 	63 62 61 00 
 
UTF-8 character literals:
u8'a' 	61 
 
UTF-16 character literals:
u'a' 	61 00 
u'¢' 	A2 00 
u'猫' 	2B 73 
 
UTF-32 character literals:
U'a' 	61 00 00 00 
U'¢' 	A2 00 00 00 
U'猫' 	2B 73 00 00 
U'🍌' 	4C F3 01 00 
 
Wide character literals:
L'a' 	61 00 00 00 
L'¢' 	A2 00 00 00 
L'猫' 	2B 73 00 00 
L'🍌' 	4C F3 01 00

[edit] 缺陷报告

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

DR 应用于 已发布的行为 正确的行为
CWG 912 C++98 不可编码的普通字符字面量未指定 指定为条件支持的
CWG 1024 C++98 要求支持多字符字面量 改为条件支持的
CWG 1656 C++98 数字转义序列的含义
在字符字面量中不清楚
指定了
P1854R4 C++98 不可编码字符字面量是条件支持的 程序将形成错误

[edit] 参考资料

  • C++23 标准 (ISO/IEC 14882:2024)
  • 5.13.3 字符字面量 [lex.ccon]
  • C++20 标准 (ISO/IEC 14882:2020)
  • 5.13.3 字符字面量 [lex.ccon]
  • C++17 标准 (ISO/IEC 14882:2017)
  • 5.13.3 字符字面量 [lex.ccon]
  • C++14 标准 (ISO/IEC 14882:2014)
  • 2.14.3 字符字面量 [lex.ccon]
  • C++11 标准 (ISO/IEC 14882:2011)
  • 2.14.3 字符字面量 [lex.ccon]
  • C++03 标准 (ISO/IEC 14882:2003)
  • 2.13.2 字符字面量 [lex.ccon]
  • C++98 标准 (ISO/IEC 14882:1998)
  • 2.13.2 字符字面量 [lex.ccon]

[edit] 另请参阅

用户定义的字面量(从 C++11 开始) 带用户定义后缀的字面量[edit]
C 文档 关于 字符常量