字符串字面量

< 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) 原始字符串字面量。用于避免转义任何字符。分隔符间的任何内容都成为字符串的一部分。若存在 前缀 则具有与上述相同的含义。

注解

字符串字面量始终要追加空字符('\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'; // 未定义行为

C 中,字符串字面量拥有类型 char[],而且可以直接赋值给(非 const)char*。C++03 也曾允许(但将其弃用,因为 C++ 中字面量是 const)。C++11 不再允许不带转型的这种赋值。

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

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\nWorld\n";
 
int main()
{
    std::cout << array1 << '\n';
    std::cout << array2 << '\n';
 
    std::cout << s1;
    std::cout << s2;
}

输出:

Foobar
Foobar
 
Hello
World
 
Hello
World

参阅

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