288 lines
33 KiB
HTML
288 lines
33 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>字符串字面量</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_language_string_literal skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">字符串字面量</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>"</b></code><span class="t-spar">s字符序列</span><span class="t-mark">(可选)</span><code><b>"</b></code></td>
|
|
<td>(1)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>L"</b></code><span class="t-spar">s字符序列</span><span class="t-mark">(可选)</span><code><b>"</b></code></td>
|
|
<td>(2)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>u8"</b></code><span class="t-spar">s字符序列</span><span class="t-mark">(可选)</span><code><b>"</b></code></td>
|
|
<td>(3)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>u"</b></code><span class="t-spar">s字符序列</span><span class="t-mark">(可选)</span><code><b>"</b></code></td>
|
|
<td>(4)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>U"</b></code><span class="t-spar">s字符序列</span><span class="t-mark">(可选)</span><code><b>"</b></code></td>
|
|
<td>(5)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">前缀</span><span class="t-mark">(可选)</span> <code><b>R"</b></code><span class="t-spar">d字符序列</span><span class="t-mark">(可选)</span><code><b>(</b></code><span class="t-spar">r字符序列</span><span class="t-mark">(可选)</span><code><b>)</b></code><span class="t-spar">d字符序列</span><span class="t-mark">(可选)</span><code><b>"</b></code></td>
|
|
<td>(6)</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">s字符序列</span></td>
|
|
<td>-</td>
|
|
<td>一个或多个<span class="t-spar">s字符</span></td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">s字符</span></td>
|
|
<td>-</td>
|
|
<td>下列之一:
|
|
<ul>
|
|
<li>一个<span class="t-spar">基础s字符</span></li>
|
|
<li>一个转义序列,定义见<a href="cpp-language-escape.html">转义序列</a></li>
|
|
<li>一个通用字符名,定义见<a href="cpp-language-escape.html">转义序列</a></li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">基础s字符</span></td>
|
|
<td>-</td>
|
|
<td>来自<span class="t-rev-inl t-until-cxx23"><span><a href="cpp-language-translation_phases.html#.E9.98.B6.E6.AE.B5_5">源字符集</a></span> <span><span class="t-mark-rev t-until-cxx23">(C++23 前)</span></span></span><span class="t-rev-inl t-since-cxx23"><span><a href="cpp-language-charset.html#.E7.BF.BB.E8.AF.91.E5.AD.97.E7.AC.A6.E9.9B.86">翻译字符集</a></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>去掉双引号(<code><b>"</b></code>)、反斜杠(<code><b>\</b></code>)和换行符后的字符</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">前缀</span></td>
|
|
<td>-</td>
|
|
<td><code><b>L</b></code>、<code><b>u8</b></code>、<code><b>u</b></code>、<code><b>U</b></code> 之一</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">d字符序列</span></td>
|
|
<td>-</td>
|
|
<td>一个或多个<span class="t-spar">d字符</span>,最多十六个</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">d字符</span></td>
|
|
<td>-</td>
|
|
<td>来自<span class="t-rev-inl t-until-cxx23"><span><a href="cpp-language-charset.html#.E5.9F.BA.E7.A1.80.E6.BA.90.E5.AD.97.E7.AC.A6.E9.9B.86">基础源字符集</a></span> <span><span class="t-mark-rev t-until-cxx23">(C++23 前)</span></span></span><span class="t-rev-inl t-since-cxx23"><span><a href="cpp-language-charset.html#.E5.9F.BA.E7.A1.80.E5.AD.97.E7.AC.A6.E9.9B.86">基础字符集</a></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>去掉括号、反斜杠和<a href="cpp-string-byte-isspace.html">空格</a>后的字符</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">r字符序列</span></td>
|
|
<td>-</td>
|
|
<td>一个或多个<span class="t-spar">r字符</span>,不得包含闭序列 <code><b>)</b></code><span class="t-spar">d字符序列</span><code><b>"</b></code></td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">r字符</span></td>
|
|
<td>-</td>
|
|
<td>来自<span class="t-rev-inl t-until-cxx23"><span><a href="cpp-language-translation_phases.html#.E9.98.B6.E6.AE.B5_5">源字符集</a></span> <span><span class="t-mark-rev t-until-cxx23">(C++23 前)</span></span></span><span class="t-rev-inl t-since-cxx23"><span><a href="cpp-language-charset.html#.E7.BF.BB.E8.AF.91.E5.AD.97.E7.AC.A6.E9.9B.86">翻译字符集</a></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>的字符</td>
|
|
</tr>
|
|
</table>
|
|
<p><br /></p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 通常字符串字面量。无前缀字符串字面量的类型是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> <span class="kw4">char</span><span class="br0">[</span>N<span class="br0">]</span></span></span>,其中 <code>N</code> 是以<span class="t-rev-inl t-until-cxx23"><span>执行窄编码</span> <span><span class="t-mark-rev t-until-cxx23">(C++23 前)</span></span></span><span class="t-rev-inl t-since-cxx23"><span><a href="cpp-language-charset.html#.E4.BB.A3.E7.A0.81.E5.8D.95.E5.85.83.E4.B8.8E.E5.AD.97.E9.9D.A2.E9.87.8F.E7.BC.96.E7.A0.81">通常字面量编码</a></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>的编码单元计的字符串的大小,包含空终止符。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 宽字符串字面量。<span class="t-c"><span class="mw-geshi cpp source-cpp">L<span class="st0">"..."</span></span></span> 字符串字面量的类型是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> <span class="kw4">wchar_t</span><span class="br0">[</span>N<span class="br0">]</span></span></span>,其中 <code>N</code> 是以<span class="t-rev-inl t-until-cxx23"><span>执行宽编码</span> <span><span class="t-mark-rev t-until-cxx23">(C++23 前)</span></span></span><span class="t-rev-inl t-since-cxx23"><span>宽字面量编码</span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>的编码单元计的字符串的大小,包含空终止符。</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> UTF-8 字符串字面量。<span class="t-c"><span class="mw-geshi cpp source-cpp">u8<span class="st0">"..."</span></span></span> 字符串字面量的类型是 <span class="t-rev-inl t-until-cxx20"><span><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> <span class="kw4">char</span><span class="br0">[</span>N<span class="br0">]</span></span></span></span> <span><span class="t-mark-rev t-until-cxx20">(C++20 前)</span></span></span><span class="t-rev-inl t-since-cxx20"><span><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> char8_t<span class="br0">[</span>N<span class="br0">]</span></span></span></span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span>,其中 <code>N</code> 是以 UTF-8 编码单元计的字符串的大小,包含空终止符。</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> UTF-16 字符串字面量。<span class="t-c"><span class="mw-geshi cpp source-cpp">u<span class="st0">"..."</span></span></span> 字符串字面量的类型是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> <span class="kw4">char16_t</span><span class="br0">[</span>N<span class="br0">]</span></span></span>,其中 <code>N</code> 是以 UTF-16 编码单元计的字符串的大小,包含空终止符。</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> UTF-32 字符串字面量。<span class="t-c"><span class="mw-geshi cpp source-cpp">U<span class="st0">"..."</span></span></span> 字符串字面量的类型是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> <span class="kw4">char32_t</span><span class="br0">[</span>N<span class="br0">]</span></span></span>,其中 <code>N</code> 是以 UTF-32 编码单元计的字符串的大小,包含空终止符。</div>
|
|
<div class="t-li1"><span class="t-li">6)</span> 原始字符串字面量。用于避免转义任何字符。分隔符间的任何内容都成为字符串的一部分。如果存在 <span class="t-spar">前缀</span> 则具有与上述相同的含义。结尾的 <span class="t-spar">d字符序列</span>需要和开头的 <span class="t-spar">d字符序列</span>一致。</div>
|
|
<p>每个(来自非原始字符串字面量的)<span class="t-spar">s字符</span> <span class="t-rev-inl t-since-cxx11"><span>或(来自原始字符串字面量的)<span class="t-spar">r字符</span></span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>均初始化字符串字面量对象中的对应元素。一个 <span class="t-spar">s字符</span> <span class="t-rev-inl t-since-cxx11"><span>或 <span class="t-spar">r字符</span></span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>当且仅当它被字符串字面量的关联字符编码中多于一个编码单元的序列表示时对应多于一个元素。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx23">
|
|
<td>
|
|
<p>如果字符缺少在关联字符编码中的表示,</p>
|
|
<ul>
|
|
<li>如果字符串字面量为通常字符串字面量或宽字符串字面量,则它是条件性支持且编码的是实现定义的编码单元序列;</li>
|
|
<li>否则(字符串字面量为 UTF 编码),该字符串字面量非良构。</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>每个数值转义序列对应单个元素。<span class="t-rev-inl t-since-cxx23"><span>如果转义序列所指定的值适合元素类型的无符号版本,则元素拥有(可能在转换到元素类型后的)指定值;否则(即指定值在范围外)该字符串字面量非良构。</span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span></p>
|
|
<h4><span class="mw-headline" id=".E6.8B.BC.E6.8E.A5">拼接</span></h4>
|
|
<p>在<a href="cpp-language-translation_phases.html">翻译阶段 6</a>(预处理器之后),毗邻的字符串字面量会被拼接起来。即 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">"Hello,"</span> <span class="st0">" world!"</span></span></span> 生成(单个)字符串 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">"Hello, world!"</span></span></span>。如果两个字符串的编码前缀相同(或者都没有编码前缀),则产生的字符串将拥有相同的编码前缀(或无前缀)。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>如果一个字符串有编码前缀而另一个没有,则无编码前缀者被认为拥有与另一者相同的编码前缀。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1">L<span class="st0">"Δx = %"</span> <a href="cpp-types-integer.html"><span class="kw177">PRId16</span></a> <span class="co1">// 在阶段 4,PRId16 展开成 "d"</span>
|
|
<span class="co1">// 在阶段 6,L"Δx = %" 与 "d" 组成 L"Δx = %d"</span></pre></div>
|
|
</div>
|
|
<p>如果 UTF-8 字符串字面量与宽字符串字面量毗邻,则程序非良构。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11 t-until-cxx23">
|
|
<td>
|
|
<p>实现可能支持或不支持任何其他编码前缀组合。这种拼接的结果是实现定义的。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span><br />
|
|
<span class="t-mark-rev t-until-cxx23">(C++23 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx23">
|
|
<td>
|
|
<p>任何其他编码前缀组合为非良构。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>字符串字面量始终要追加空字符(<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'<span class="es5">\0</span>'</span></span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp">L<span class="st0">'<span class="es5">\0</span>'</span></span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">char16_t</span><span class="br0">(</span><span class="br0">)</span></span></span> 等):因此,字符串字面量 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">"Hello"</span></span></span> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">const</span> <span class="kw4">char</span><span class="br0">[</span><span class="nu0">6</span><span class="br0">]</span></span></span>,并保有字符 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'H'</span></span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'e'</span></span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'l'</span></span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'l'</span></span></span>、<span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'o'</span></span></span> 及 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">'<span class="es5">\0</span>'</span></span></span>。</p>
|
|
<p>通常字符串字面量 <span class="t-v">(1)</span> 和宽字符串字面量 <span class="t-v">(2)</span> 的编码是实现定义的。例如,gcc 用<a rel="nofollow" class="external text" href="https://gcc.gnu.org/onlinedocs/cpp/Invocation.html">命令行选项</a> <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">-</span>fexec<span class="sy2">-</span>charset</span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="sy2">-</span>fwide<span class="sy2">-</span>exec<span class="sy2">-</span>charset</span></span> 选择它们。</p>
|
|
<p>字符串字面量拥有<a href="cpp-language-storage_duration.html">静态存储期</a>,从而在程序生存期间存在于内存中。</p>
|
|
<p>字符串字面量可用于<a href="cpp-language-aggregate_initialization.html">初始化字符数组</a>。如果数组初始化类似 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">char</span> str<span class="br0">[</span><span class="br0">]</span> <span class="sy1">=</span> <span class="st0">"foo"</span><span class="sy4">;</span></span></span>,那么 <span class="t-c"><span class="mw-geshi cpp source-cpp">str</span></span> 将含有字符串 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="st0">"foo"</span></span></span> 的副本。</p>
|
|
<p>字符串字面量能否重叠以及同一字符串字面量的相继求值是否产生同一对象是未指明的。这意味着以指针比较时,相同的字符串字面量比较时可能相等或不相等。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw4">bool</span> b <span class="sy1">=</span> <span class="st0">"bar"</span> <span class="sy1">==</span> <span class="nu0">3</span><span class="sy2">+</span><span class="st0">"foobar"</span> <span class="co1">// 可为 true 或 false,由实现定义</span></pre></div>
|
|
</div>
|
|
<p>试图修改字符串字面量导致<i>未定义行为</i>:它们可以存储于只读存储(例如 <code>.rodata</code>)或与其他字符串字面量合并:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> pc <span class="sy1">=</span> <span class="st0">"Hello"</span><span class="sy4">;</span>
|
|
<span class="kw4">char</span><span class="sy2">*</span> p <span class="sy1">=</span> <span class="kw1">const_cast</span><span class="sy1"><</span><span class="kw4">char</span><span class="sy2">*</span><span class="sy1">></span><span class="br0">(</span>pc<span class="br0">)</span><span class="sy4">;</span>
|
|
p<span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span> <span class="sy1">=</span> <span class="st0">'M'</span><span class="sy4">;</span> <span class="co1">// 未定义行为</span></pre></div>
|
|
</div>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx11">
|
|
<td>
|
|
<p>字符串字面量可转换为且可赋值给非 const 的 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">char</span><span class="sy2">*</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">wchar_t</span><span class="sy2">*</span></span></span> 以与 C 兼容, C 中字符串字面量类型为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">char</span><span class="br0">[</span>N<span class="br0">]</span></span></span> 与 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">wchar_t</span><span class="br0">[</span>N<span class="br0">]</span></span></span>。 这种隐式转换被弃用。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx11">(C++11 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>字符串字面量不可转换为或赋值给非 const 的 <span class="t-c"><span class="mw-geshi cpp source-cpp">CharT<span class="sy2">*</span></span></span>。若想要这种转换则必须用显式转型(例如 <a href="cpp-language-const_cast.html"><code>const_cast</code></a>)。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>字符串字面量不需要是一个空终止字符序列:如果字符串字面量包含内嵌的空字符,那么它表示含有多于一条字符串的数组。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> p <span class="sy1">=</span> <span class="st0">"abc<span class="es5">\0</span>def"</span><span class="sy4">;</span> <span class="co1">// std::strlen(p) == 3 ,但数组大小为 8</span></pre></div>
|
|
</div>
|
|
<p>如果字符串字面量中一个十六进制转义后随一个合法十六进制数位,则可能因非法转义序列而编译失败。此时可以拼接字符串:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co1">//const char* p = "\xfff"; // 错误:十六进制转义序列在范围外</span>
|
|
<span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> p <span class="sy1">=</span> <span class="st0">"<span class="es2">\xff</span>"</span><span class="st0">"f"</span><span class="sy4">;</span> <span class="co1">// OK :此字面量是保有 {'\xff','f','\0'} 的 const char[3]</span></pre></div>
|
|
</div>
|
|
<p>尽管 C++11 中允许混合的宽字符串字面量连接,所有已知的 C++ 编译器都拒绝这种连接,而其使用经验是未知的。结果 C++23 中移除了对混合宽字符串字面量连接的允许。</p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
|
|
<span class="kw4">char</span> array1<span class="br0">[</span><span class="br0">]</span> <span class="sy1">=</span> <span class="st0">"Foo"</span> <span class="st0">"bar"</span><span class="sy4">;</span>
|
|
<span class="co1">// 同</span>
|
|
<span class="kw4">char</span> array2<span class="br0">[</span><span class="br0">]</span> <span class="sy1">=</span> <span class="br0">{</span> <span class="st0">'F'</span>, <span class="st0">'o'</span>, <span class="st0">'o'</span>, <span class="st0">'b'</span>, <span class="st0">'a'</span>, <span class="st0">'r'</span>, <span class="st0">'<span class="es5">\0</span>'</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> s1 <span class="sy1">=</span> R<span class="st0">"foo(
|
|
Hello
|
|
World
|
|
)foo"</span><span class="sy4">;</span>
|
|
<span class="co1">// 同</span>
|
|
<span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> s2 <span class="sy1">=</span> <span class="st0">"<span class="es1">\n</span>Hello<span class="es1">\n</span> World<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="co1">// 同</span>
|
|
<span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> s3 <span class="sy1">=</span> <span class="st0">"<span class="es1">\n</span>"</span>
|
|
<span class="st0">"Hello<span class="es1">\n</span>"</span>
|
|
<span class="st0">" World<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> array1 <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> array2 <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> s1 <span class="sy1"><<</span> s2 <span class="sy1"><<</span> s3<span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">Foobar
|
|
Foobar
|
|
|
|
Hello
|
|
World
|
|
|
|
Hello
|
|
World
|
|
|
|
Hello
|
|
World</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E7.BC.BA.E9.99.B7.E6.8A.A5.E5.91.8A">缺陷报告</span></h3>
|
|
<p>下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。</p>
|
|
<table class="dsctable" style="font-size:0.8em">
|
|
<tr>
|
|
<th>DR</th>
|
|
<th>应用于</th>
|
|
<th>出版时的行为</th>
|
|
<th>正确行为</th>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue1823">CWG 1823</a></td>
|
|
<td>C++98</td>
|
|
<td>字符串字面量是否有别是实现定义的</td>
|
|
<td>区别性未指明,相同字符串字面量能产生不同对象</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td><a href="cpp-language-user_literal.html">用户定义字面量</a><span class="t-mark-rev t-since-cxx11">(C++11)</span></td>
|
|
<td>拥有用户定义后缀的字面量</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|