132 lines
14 KiB
HTML
132 lines
14 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-c_language_compound_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="c.html">c</a>‎ | <a href="c-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>就地构造一个指定类型的无名对象,在只需要一次数组、结构体或联合体变量时使用。</p>
|
|
<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">type</span> <code><b>)</b></code> <code><b>{</b></code> <span class="t-spar">initializer-list</span> <code><b>}</b></code></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td><span class="t-mark-rev t-since-c99">(C99 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<p>其中</p>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">type</span></td>
|
|
<td>-</td>
|
|
<td>指定任何完整对象类型或未知大小的数组的<a href="c-language-types.html#.E7.B1.BB.E5.9E.8B.E5.90.8D">类型名</a>,但不能是 VLA</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">initializer-list</span></td>
|
|
<td>-</td>
|
|
<td>适合 <span class="t-spar">type</span> 类型变量<a href="c-language-initialization.html">初始化</a>的初始化器列表</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>复合字面量构造一个 <span class="t-spar">type</span> 所指定类型的无名对象,并以 <span class="t-spar">initializer-list</span> 的指定初始化之。</p>
|
|
<p>复合字面量的类型是 <span class="t-spar">type</span> (除非 <span class="t-spar">type</span> 是未知大小的数组;如在<a href="c-language-array_initialization.html">数组初始化</a>中一般从 <span class="t-spar">initializer-list</span> 推导出其大小)。</p>
|
|
<p>复合字面量的值类别是<a href="c-language-value_category.html">左值</a>(能取其地址)。</p>
|
|
<p>若复合字面量出现于文件作用域,则其求值所得的无名对象拥有静态<a href="c-language-storage_duration.html">存储期</a>,若复合字面量出现于块作用域,则该对象拥有自动<a href="c-language-storage_duration.html">存储期</a>(此情况下对象的<a href="c-language-lifetime.html">生存期</a>结束于外围块的结尾)。</p>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E6.84.8F">注意</span></h3>
|
|
<p>字符或宽字符数组类型的 const 限定复合字面量,可能会与<a href="c-language-string_literal.html">字符串字面量</a>共享存储。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="br0">(</span><span class="kw4">const</span> <span class="kw4">char</span> <span class="br0">[</span><span class="br0">]</span><span class="br0">)</span><span class="br0">{</span><span class="st0">"abc"</span><span class="br0">}</span> <span class="sy1">==</span> <span class="st0">"abc"</span> <span class="co1">// 可以为 1 或 0 ,实现定义</span></pre></div>
|
|
</div>
|
|
<p>每个复合字面量仅在其作用域内创建一个对象:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">int</span> f <span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw1">struct</span> s <span class="br0">{</span><span class="kw4">int</span> i<span class="sy4">;</span><span class="br0">}</span> <span class="sy2">*</span>p <span class="sy1">=</span> <span class="nu0">0</span>, <span class="sy2">*</span>q<span class="sy4">;</span>
|
|
<span class="kw4">int</span> j <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
|
|
again<span class="sy4">:</span>
|
|
q <span class="sy1">=</span> p, p <span class="sy1">=</span> <span class="sy3">&</span><span class="br0">(</span><span class="br0">(</span><span class="kw1">struct</span> s<span class="br0">)</span><span class="br0">{</span> j<span class="sy2">++</span> <span class="br0">}</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>j <span class="sy1"><</span> <span class="nu0">2</span><span class="br0">)</span> <span class="kw1">goto</span> again<span class="sy4">;</span> <span class="co1">// 注意:若使用循环,则其作用域会结束于此,</span>
|
|
<span class="co1">// 这会终止复合字面量的生存期,</span>
|
|
<span class="co1">// 令 p 为悬垂指针</span>
|
|
<span class="kw1">return</span> p <span class="sy1">==</span> q <span class="sy3">&&</span> q<span class="sy2">-</span><span class="sy1">></span>i <span class="sy1">==</span> <span class="nu0">1</span><span class="sy4">;</span> <span class="co1">// 始终返回 1</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>因为复合字面量是无名的,一个复合字面量不能引用自身(一个具名结构体可以包含指向其自身的指针)。</p>
|
|
<p>虽然复合字面量的语法和<a href="c-language-cast.html">转型</a>相似,重要的区别是转型是非左值表达式,而复合字面量是左值。</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="c source-c">
|
|
<pre class="de1"><span class="kw4">int</span> <span class="sy2">*</span>p <span class="sy1">=</span> <span class="br0">(</span><span class="kw4">int</span><span class="br0">[</span><span class="br0">]</span><span class="br0">)</span><span class="br0">{</span><span class="nu0">2</span>, <span class="nu0">4</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 创建一个无名的 int[2] 类型静态存储数组</span>
|
|
<span class="co1">// 初始数组为值 {2, 4}</span>
|
|
<span class="co1">// 创建指向数组首元素的指针 p</span>
|
|
<span class="kw4">const</span> <span class="kw4">float</span> <span class="sy2">*</span>pc <span class="sy1">=</span> <span class="br0">(</span><span class="kw4">const</span> <span class="kw4">float</span> <span class="br0">[</span><span class="br0">]</span><span class="br0">)</span><span class="br0">{</span><span class="nu19">1e0</span>, <span class="nu19">1e1</span>, <span class="nu19">1e2</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 只读复合字面量</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> n <span class="sy1">=</span> <span class="nu0">2</span>, <span class="sy2">*</span>p <span class="sy1">=</span> <span class="sy3">&</span>n<span class="sy4">;</span>
|
|
p <span class="sy1">=</span> <span class="br0">(</span><span class="kw4">int</span> <span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span><span class="br0">)</span><span class="br0">{</span><span class="sy2">*</span>p<span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 创建一个无名的 int[2] 类型自动存储数组</span>
|
|
<span class="co1">// 初始化首个元素为之前 *p 所持有的值</span>
|
|
<span class="co1">// 初始化第二个元素为零</span>
|
|
<span class="co1">// 将首元素的地址存储到 p</span>
|
|
|
|
<span class="kw1">struct</span> point <span class="br0">{</span><span class="kw4">double</span> x,y<span class="sy4">;</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw4">void</span> drawline1<span class="br0">(</span><span class="kw1">struct</span> point from, <span class="kw1">struct</span> point to<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw4">void</span> drawline2<span class="br0">(</span><span class="kw1">struct</span> point <span class="sy2">*</span>from, <span class="kw1">struct</span> point <span class="sy2">*</span>to<span class="br0">)</span><span class="sy4">;</span>
|
|
drawline1<span class="br0">(</span><span class="br0">(</span><span class="kw1">struct</span> point<span class="br0">)</span><span class="br0">{</span>.<span class="me1">x</span><span class="sy1">=</span><span class="nu0">1</span>, .<span class="me1">y</span><span class="sy1">=</span><span class="nu0">1</span><span class="br0">}</span>, <span class="co1">// 创建二个块作用域的结构体</span>
|
|
<span class="br0">(</span><span class="kw1">struct</span> point<span class="br0">)</span><span class="br0">{</span>.<span class="me1">x</span><span class="sy1">=</span><span class="nu0">3</span>, .<span class="me1">y</span><span class="sy1">=</span><span class="nu0">4</span><span class="br0">}</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 然后调用 drawline1 ,以值传递</span>
|
|
drawline2<span class="br0">(</span><span class="sy3">&</span><span class="br0">(</span><span class="kw1">struct</span> point<span class="br0">)</span><span class="br0">{</span>.<span class="me1">x</span><span class="sy1">=</span><span class="nu0">1</span>, .<span class="me1">y</span><span class="sy1">=</span><span class="nu0">1</span><span class="br0">}</span>, <span class="co1">// 创建二个块作用域的结构体</span>
|
|
<span class="sy3">&</span><span class="br0">(</span><span class="kw1">struct</span> point<span class="br0">)</span><span class="br0">{</span>.<span class="me1">x</span><span class="sy1">=</span><span class="nu0">3</span>, .<span class="me1">y</span><span class="sy1">=</span><span class="nu0">4</span><span class="br0">}</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 然后调用 drawline2 ,传递其地址</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-11">
|
|
<ul>
|
|
<li>C11 标准(ISO/IEC 9899:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.5.2.5 Compound literals (p: 85-87)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<div class="t-ref-std-c99">
|
|
<ul>
|
|
<li>C99 标准(ISO/IEC 9899:1999):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.5.2.5 Compound literals (p: 75-77)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|