220 lines
16 KiB
HTML
220 lines
16 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_constant_expression 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>表达式的数种变体被称为<i>常量表达式</i>。</p>
|
|
<h3><span class="mw-headline" id=".E9.A2.84.E5.A4.84.E7.90.86.E5.99.A8.E5.B8.B8.E9.87.8F.E8.A1.A8.E8.BE.BE.E5.BC.8F">预处理器常量表达式</span></h3>
|
|
<p>后随 <a href="c-preprocessor-conditional.html">#if 或 #elif</a> 的表达式必须展开成</p>
|
|
<ul>
|
|
<li><a href="c-language-operator_assignment.html">赋值</a>、<a href="c-language-operator_incdec.html">自增、自减</a>、<a href="c-language-operator_other.html#.E5.87.BD.E6.95.B0.E8.B0.83.E7.94.A8">函数调用</a>或<a href="c-language-operator_other.html#.E9.80.97.E5.8F.B7.E8.BF.90.E7.AE.97.E7.AC.A6">逗号</a>以外的,参数为预处理器常量表达式的<a href="c-language-expressions.html#.E8.BF.90.E7.AE.97.E7.AC.A6">运算符</a></li>
|
|
<li><a href="c-language-integer_constant.html">整数常量</a></li>
|
|
<li><a href="c-language-character_constant.html">字符常量</a></li>
|
|
<li>特殊预处理器运算符 <code>defined</code></li>
|
|
</ul>
|
|
<p>字符常量在 <code>#if</code> 表达式中求值时,可能以源字符集、执行字符集或某个其他实现定义字符集转译。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-c99">
|
|
<td>
|
|
<p><code>#if</code> 表达式中,对有符号类型以 <span class="t-lc"><a href="c-types-integer.html">intmax_t</a></span> 的语义,而对无符号类型以 <span class="t-lc"><a href="c-types-integer.html">uintmax_t</a></span> 的语义进行整数算术。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-c99">(C99 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.95.B4.E6.95.B0.E5.B8.B8.E9.87.8F.E8.A1.A8.E8.BE.BE.E5.BC.8F">整数常量表达式</span></h3>
|
|
<p>整数常量表达式是仅由下列内容组成的表达式</p>
|
|
<ul>
|
|
<li><a href="c-language-operator_assignment.html">赋值</a>、<a href="c-language-operator_incdec.html">自增、自减</a>、<a href="c-language-operator_other.html#.E5.87.BD.E6.95.B0.E8.B0.83.E7.94.A8">函数调用</a>或<a href="c-language-operator_other.html#.E9.80.97.E5.8F.B7.E8.BF.90.E7.AE.97.E7.AC.A6">逗号</a>以外的<a href="c-language-expressions.html#.E8.BF.90.E7.AE.97.E7.AC.A6">运算符</a>,除了<a href="c-language-cast.html">转型</a>运算符只能转型算术类型为整数类型</li>
|
|
<li><a href="c-language-integer_constant.html">整数常量</a></li>
|
|
<li><a href="c-language-enum.html">枚举常量</a></li>
|
|
<li><a href="c-language-character_constant.html">字符常量</a></li>
|
|
<li><a href="c-language-floating_constant.html">浮点常量</a>,但仅若立即以之为转型到整数类型的操作数</li>
|
|
<li><span class="t-rev-inl t-since-c99"><span>操作数非 VLA 的</span> <span><span class="t-mark-rev t-since-c99">(C99 起)</span></span></span><a href="c-language-sizeof.html"><code>sizeof</code></a> 运算符</li>
|
|
</ul>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-c11">
|
|
<td>
|
|
<ul>
|
|
<li><a href="c-language-_Alignof.html"><code>_Alignof</code></a> 运算符</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-c11">(C11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>整数常量表达式在编译时求值。下列语境要求被称为<i>整数常量表达式</i>的表达式:</p>
|
|
<ul>
|
|
<li><a href="c-language-bit_field.html">位域</a>的大小</li>
|
|
<li><a href="c-language-enum.html">枚举常量</a>的值</li>
|
|
<li><a href="c-language-switch.html">switch 语句</a>的 <code>case</code> 标号</li>
|
|
<li><span class="t-rev-inl t-since-c99"><span>非 VLA</span> <span><span class="t-mark-rev t-since-c99">(C99 起)</span></span></span>数组的大小</li>
|
|
<li>整数到指针<a href="c-language-conversion.html">隐式转换</a>。</li>
|
|
</ul>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-c99">
|
|
<td>
|
|
<ul>
|
|
<li><a href="c-language-array_initialization.html">数组指派符</a>的下标</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-c99">(C99 起)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-c11">
|
|
<td>
|
|
<ul>
|
|
<li><a href="c-language-_Static_assert.html"><code>_Static_assert</code></a> 的首参数</li>
|
|
<li><a href="c-language-_Alignas.html"><code>_Alignas</code></a> 的整数参数</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-c11">(C11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E9.9D.99.E6.80.81.E5.88.9D.E5.A7.8B.E5.8C.96.E5.99.A8">静态初始化器</span></h3>
|
|
<p>拥有静态和线程局域<a href="c-language-storage_duration.html">存储期</a>的对象<a href="c-language-initialization.html">初始化器</a>中使用的表达式必须是下列表达式之一</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> <i>算术常量表达式</i>,即由下列内容构成的任何算术类型表达式
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li><a href="c-language-operator_assignment.html">赋值</a>、<a href="c-language-operator_incdec.html">自增、自减</a>、<a href="c-language-operator_other.html#.E5.87.BD.E6.95.B0.E8.B0.83.E7.94.A8">函数调用</a>或<a href="c-language-operator_other.html#.E9.80.97.E5.8F.B7.E8.BF.90.E7.AE.97.E7.AC.A6">逗号</a>以外的<a href="c-language-expressions.html#.E8.BF.90.E7.AE.97.E7.AC.A6">运算符</a>,除了<a href="c-language-cast.html">转型</a>运算符必须转换算术类型到其他算术类型</li>
|
|
<li><a href="c-language-integer_constant.html">整数常量</a></li>
|
|
<li><a href="c-language-floating_constant.html">浮点常量</a></li>
|
|
<li><a href="c-language-enum.html">枚举常量</a></li>
|
|
<li><a href="c-language-character_constant.html">字符常量</a></li>
|
|
<li><span class="t-rev-inl t-since-c99"><span>操作数非 VLA 的</span> <span><span class="t-mark-rev t-since-c99">(C99 起)</span></span></span><a href="c-language-sizeof.html"><code>sizeof</code></a> 运算符</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-c11">
|
|
<td>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li><a href="c-language-_Alignof.html"><code>_Alignof</code></a> 运算符</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-c11">(C11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 空指针常量 <span class="t-lc"><a href="c-types-NULL.html">NULL</a></span></div>
|
|
<div class="t-li1"><span class="t-li">3)</span> <i>地址常量表达式</i>,即
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>空指针</li>
|
|
<li>指代静态<a href="c-language-storage_duration.html">存储期</a>的对象的<a href="c-language-value_category.html">左值</a>,或函数指代器,通过下列方式之一转换为指针</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>用一元取址运算符</li>
|
|
<li>转型整数常量到指针</li>
|
|
<li>数组到指针或函数到指针<a href="c-language-conversion.html">隐式转换</a></li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 某完整对象类型的<i>地址常量表达式</i>加或减一个<i>整数常量表达式</i></div>
|
|
<div class="t-li1"><span class="t-li">5)</span> 实现所接受的其他形式之一的常量表达式。</div>
|
|
<p>不同于整数常量表达式,不要求静态初始化器在编译时求值;编译器有将这种初始化器转变为在程序启动前调用的可执行代码的自由。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">static</span> <span class="kw4">int</span> i <span class="sy1">=</span> <span class="nu0">2</span> <span class="sy3">||</span> <span class="nu0">1</span> <span class="sy2">/</span> <span class="nu0">0</span><span class="sy4">;</span> <span class="co1">// 初始化 i 为值 1</span></pre></div>
|
|
</div>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:其他小示例</td>
|
|
</tr>
|
|
</table>
|
|
<p>浮点静态初始化器的值的精度决不低于在运行时执行的同一表达式,但可以高于后者。</p>
|
|
<h3><span class="mw-headline" id=".E6.B5.AE.E7.82.B9.E5.B8.B8.E9.87.8F.E8.A1.A8.E8.BE.BE.E5.BC.8F">浮点常量表达式</span></h3>
|
|
<p>不用于静态初始化器中的浮点类型的算术常量表达式,始终如同在运行时求值,受<a href="c-numeric-fenv-FE_round.html">当前舍入</a>影响(若 <a href="c-preprocessor-impl.html">FENV_ACCESS</a> 为 ON ),并报告 <a href="c-numeric-math-math_errhandling.html"><tt>math_errhandling</tt></a> 中指定的错误。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co2">#pragma STDC FENV_ACCESS ON</span>
|
|
<span class="kw4">static</span> <span class="kw4">float</span> x <span class="sy1">=</span> <span class="nu16">0.0</span><span class="sy2">/</span><span class="nu16">0.0</span><span class="sy4">;</span> <span class="co1">// 静态初始化器:不引发异常</span>
|
|
<span class="kw4">float</span> w<span class="br0">[</span><span class="br0">]</span> <span class="sy1">=</span> <span class="br0">{</span> <span class="nu16">0.0</span><span class="sy2">/</span><span class="nu16">0.0</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 引发异常</span>
|
|
<span class="kw4">float</span> y <span class="sy1">=</span> <span class="nu16">0.0</span><span class="sy2">/</span><span class="nu16">0.0</span><span class="sy4">;</span> <span class="co1">// 引发异常</span>
|
|
<span class="kw4">double</span> z <span class="sy1">=</span> <span class="nu16">0.0</span><span class="sy2">/</span><span class="nu16">0.0</span><span class="sy4">;</span> <span class="co1">// 引发异常</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>若表达式求值到的值不能以其类型表示,则不能以之为常量表达式。</p>
|
|
<p>实现可以接受其他形式的常量表达式。然而,这些常量表达式不被认为是整数常量表达式、算术常量表达式或地址常量表达式,从而不能用于要求这些种类的常量表达式的语境。</p>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-17">
|
|
<ul>
|
|
<li>C17 标准(ISO/IEC 9899:2018):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.6 Constant expressions (p: 76-77)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-11">
|
|
<ul>
|
|
<li>C11 标准(ISO/IEC 9899:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.6 Constant expressions (p: 106-107)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c99">
|
|
<ul>
|
|
<li>C99 标准(ISO/IEC 9899:1999):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.6 Constant expressions (p: 95-96)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c89">
|
|
<ul>
|
|
<li>C89/C90 标准(ISO/IEC 9899:1990):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>3.4 CONSTANT EXPRESSIONS</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin"></table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|