字符串字面量

来自cppreference.com
< cpp‎ | language

语法

" 串字符序列 " (1)
L" 串字符序列 " (2)
u8" 串字符序列 " (3) (C++11 起)
u" 串字符序列 " (4) (C++11 起)
U" 串字符序列 " (5) (C++11 起)
前缀(可选) R"分隔符( 原始字符 )分隔符" (6) (C++11 起)

解释

串字符系列 - 零或更多个 串字符 的序列。 串字符 是下列之一
  • 来自源字符集的字符,除了双引号 "、反斜杠 \ 或换行符
  • 转义序列,定义于转义序列
  • 通用字符名,定义于转义序列
前缀 - Lu8uU 之一
分隔符 - 除了括号、反斜杠和空格以外的任何源字符所构成的字符序列(可为空,长度至多 16 个字符)
原始字符 - 任何字符序列,但必须不含闭序列 )分隔符"


1) 窄多字节字符串字面量。无前缀字符串字面量的类型是 const char[N],其中 N 是以执行窄编码的编码单元计的字符串的大小,包含空终止符。
2) 宽字符串字面量。L"..." 字符串字面量的类型是 const wchar_t[N],其中 N 是以执行宽编码的编码单元计的字符串的大小,包含空终止符。
3) UTF-8 编码的字符串字面量。u8"..." 字符串字面量的类型是 const char[N] (C++20 前)const char8_t[N] (C++20 起),其中 N 是以 UTF-8 编码单元计的字符串的大小,包含空终止符。
4) UTF-16 编码的字符串字面量。u"..." 字符串字面量的类型是 const char16_t[N],其中 N 是以 UTF-16 编码单元计的字符串的大小,包含空终止符。
5) UTF-32 编码的字符串字面量。U"..." 字符串字面量的类型是 const char32_t[N],其中 N 是以 UTF-32 编码单元计的字符串的大小,包含空终止符。
6) 原始字符串字面量。用于避免转义任何字符。分隔符间的任何内容都成为字符串的一部分。若存在 前缀 则具有与上述相同的含义。

每个 串字符 初始化字符串字面量对象中的对应元素。一个 串字符 对应多于一个元素当且仅当它由字符串字面量的关联字符编码中多于一个编码单元的序列表示。

若字符缺少在关联字符编码中的表示,

  • 则若字符串字面量为通常字符串字面量或宽字符串字面量,则它是条件性支持的,而编码的是实现定义的编码单元序列;
  • 否则(字符串字面量为 UTF 编码),字符串字面量非良构。
(C++23 起)

每个数值转义序列对应单个元素。若转义序列所指定的值适合元素类型的无符号版本,则元素拥有(可能在转换到元素类型后的)指定值;否则(指定值在范围外)字符串字面量非良构。 (C++23 起)

注解

字符串字面量始终要追加空字符('\0'L'\0'char16_t() 等):因此,字符串字面量 "Hello"const char[6],并保有字符 'H''e''l''l''o''\0'

窄多字节字符串字面量 (1) 与宽字符串字面量 (2) 的编码是实现定义的。例如,gcc 用命令行选项 -fexec-charset-fwide-exec-charset 选择它们。

翻译阶段 6(预处理器之后)将毗邻的字符串字面量拼接起来。即 "Hello,"  " world!" 生成(单个)字符串 "Hello, world!"。若两个字符串带有同一编码前缀(或无一带有),则产生的字符串将拥有相同的编码前缀(或无前缀)。

若一个字符串有编码前缀而另一个没有,则无编码前缀者被认为拥有与另一者相同的编码前缀。

L"Δx = %" PRId16 // 在阶段 4,PRId16 展开成 "d"
                 // 在阶段 6,L"Δx = %" 与 "d" 组成 L"Δx = %d"

若 UTF-8 字符串字面量与宽字符串字面量毗邻,则程序非良构。

(C++11 起)

实现可能或可能不支持任何其他编码前缀组合。这种拼接的结果是实现定义的。

字符串字面量拥有静态存储期,从而在程序生存期间存在于内存中。

字符串字面量可用于初始化字符数组。若数组初始化类似 char str[] = "foo";,则 str 将含有字符串 "foo" 的副本。

允许但不要求编译器将相等或重叠的字符串字面量的存储合并起来。这意味着以指针比较时,相同的字符串字面量比较时可能或可能不相等。

bool b = "bar" == 3+"foobar" // 可为 true 或 false,由实现定义

试图修改字符串字面量导致未定义行为:它们可以存储于只读存储(例如 .rodata)或与其他字符串字面量合并:

const char* pc = "Hello";
char* p = const_cast<char*>(pc);
p[0] = 'M'; // 未定义行为

字符串字面量可转换为且可赋值给非 const 的 char*wchar_t* 以与 C 兼容, C 中字符串字面量类型为 char[N]wchar_t[N]。 这种隐式转换被弃用。

(C++11 前)

字符串字面量不可转换为或赋值给非 const 的 CharT*。若想要这种转换则必须用显式转型(例如 const_cast)。

(C++11 起)

字符串字面量不需要是一个空终止字符序列:若字符串字面量有内嵌的空字符,则它表示含有多于一条字符串的数组。

const char* p = "abc\0def"; // std::strlen(p) == 3 ,但数组大小为 8

若字符串字面量中一个合法十六进制数位跟随一个十六进制转义之后,则可能因非法转义序列而编译失败。字符串连接可用作替代方案:

//const char* p = "\xfff"; // 错误:十六进制转义序列在范围外
const char* p = "\xff""f"; // OK :此字面量是保有 {'\xff','f','\0'} 的 const char[3]

示例

#include <iostream>
 
char array1[] = "Foo" "bar";
// 同
char array2[] = { 'F', 'o', 'o', 'b', 'a', 'r', '\0' };
 
const char* s1 = R"foo(
Hello
  World
)foo";
// 同
const char* s2 = "\nHello\n  World\n";
// 同
const char* s3 = "\n"
                 "Hello\n"
                 "  World\n";
int main()
{
    std::cout << array1 << '\n';
    std::cout << array2 << '\n';
    std::cout << s1 << s2 << s3;
}

输出:

Foobar
Foobar
 
Hello
  World
 
Hello
  World
 
Hello
  World

参阅

用户定义字面量(C++11) 拥有用户定义后缀的字面量