Character literal
目录 |
语法
'
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 | - | 来自 基本源字符集 (C++23 前) 翻译字符集 (C++23 起) 的字符,但不包括单引号 ' 、反斜杠 \ 或换行符 |
| c-char-sequence | - | 两个或更多 c-char 的序列 |
说明
不可编码字符
| (C++23 前) |
数值转义序列
数值(八进制和十六进制)转义序列可用于指定字符的值。
|
若字符字面量仅包含单个数值转义序列,且该转义序列所指定的值可由其类型的无符号版本表示,则该字符字面量的值等于所指定的值(可能经过向字符类型的转换后)。 UTF- N 字符字面量可具有其类型所能表示的任意值。若该值不对应于有效的 Unicode 码位,或其对应码位无法以 UTF- N 单码元形式表示,仍可通过具有该值的数值转义序列来指定。例如 u8 ' \xff ' 是合法形式,且等于 char8_t ( 0xFF ) 。 |
(since C++23) |
|
若在普通或宽字符字面量中使用的数值转义序列所指定的值无法分别由 char 或 wchar_t 表示,则该字符字面量的值由实现定义。 |
(C++23 前) |
|
若在具有单个 c-char 的普通或宽字符字面量中使用的数值转义序列所指定的值可分别由 char 或 wchar_t 底层类型的无符号版本表示,则该字面量的值为该无符号整数类型的整数值,且指定值被转换为字面量的类型。否则程序非良构。 |
(C++23 起) |
|
若用于UTF-
N
字符字面量的数值转义序列所指定的值无法由对应的
|
(C++11起) |
注释
多字符字面量是从B编程语言继承到C语言的特性。虽然C或C++标准未作规范,但大多数编译器(MSVC是显著例外)按照B语言的规范实现多字符字面量:字面量中每个字符的值以大端序、零填充、右对齐的方式初始化目标整数的连续字节,例如 ' \1 ' 的值是 0x00000001 ,而 ' \1 \2 \3 \4 ' 的值是 0x01020304 。
在C语言中,字符常量如 'a' 或 ' \n ' 的类型是 int ,而非 char 。
示例
#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 }
可能的输出:
普通字符字面量: 'a' 61 '*' 2A 普通多字符字面量: 'ab' 62 61 00 00 'abc' 63 62 61 00 UTF-8 字符字面量: u8'a' 61 UTF-16 字符字面量: u'a' 61 00 u'¢' A2 00 u'猫' 2B 73 UTF-32 字符字面量: U'a' 61 00 00 00 U'¢' A2 00 00 00 U'猫' 2B 73 00 00 U'🍌' 4C F3 01 00 宽字符字面量: L'a' 61 00 00 00 L'¢' A2 00 00 00 L'猫' 2B 73 00 00 L'🍌' 4C F3 01 00
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 适用标准 | 发布时行为 | 正确行为 |
|---|---|---|---|
| CWG 912 | C++98 | 不可编码的普通字符字面量未作规定 | 规定为条件性支持 |
| CWG 1024 | C++98 | 要求必须支持多字符字面量 | 改为条件性支持 |
| CWG 1656 | C++98 | 字符字面量中数值转义序列的含义不明确 | 已作明确规定 |
| P1854R4 | C++98 | 不可编码字符字面量属于条件性支持 | 程序属于非良构 |
参考文献
- 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]
参见
| 用户定义字面量 (C++11) | 带有用户定义后缀的字面量 |
|
C 文档
关于
字符常量
|
|