Namespaces
Variants

Character literal

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

目录

语法

' 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 的序列

说明

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 10646 c-char 的码位值,前提是该码位值可用单个 UTF-8 代码单元表示(即 c-char 在 0x0-0x7F 范围内,含边界值)。
3) UTF-16 字符字面量,例如 u '猫' ,但不包括 u '🍌' u ' \U0001f34c ' )。此类字面量的类型为 char16_t ,其值等于 ISO/IEC 10646 标准中 c-char 的码点值,前提是该码点值可用单个 UTF-16 代码单元表示(即 c-char 处于 0x0-0xFFFF 范围内,含边界值)。
4) UTF-32 字符字面量,例如 U '猫' U '🍌' 。此类字面量的类型为 char32_t ,其值等于 c-char ISO/IEC 10646 标准中的码位值。
5) 宽字符字面量,例如 L 'β' L '猫' 。此类字面量具有 wchar_t 类型,其值等于 执行宽字符集中 c-char 对应的值 (C++23 前) 宽字符编码中对应的码点 (C++23 起)
6) 普通多字符字面量 (C++23 前) 多字符字面量 (C++23 起) ,例如 'AB' ,受条件支持,具有类型 int 和实现定义的值。
7) 宽多字符字面量,例如 L 'AB' ,是条件性支持的,具有 wchar_t 类型和由实现定义的值。

不可编码字符

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 前)

数值转义序列

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

若字符字面量仅包含单个数值转义序列,且该转义序列所指定的值可由其类型的无符号版本表示,则该字符字面量的值等于所指定的值(可能经过向字符类型的转换后)。

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 字符字面量的数值转义序列所指定的值无法由对应的 char N _t 类型表示, 则该字符字面量的值由实现定义 (C++17前) 程序非良构 (C++17起)

(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 文档 关于 字符常量