274 lines
20 KiB
HTML
274 lines
20 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_enum 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>是独立的<a href="c-language-types.html">类型</a>,其值为包含所有其显示命名的常量(<i>枚举常量</i>)的<i>底层类型</i>的值。</p>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<p>枚举类型在<a href="c-language-declarations.html">声明文法</a>中以跟随的<i>枚举说明符</i>作为 <span class="t-spar">类型说明符</span> 声明:</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>enum</b></code> <span class="t-spar">属性声明符序列</span><span class="t-mark">(可选)</span> <span class="t-spar">标识符</span><span class="t-mark">(可选)</span> <code><b>{</b></code> <span class="t-spar">枚举项列表</span> <code><b>}</b></code></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<p>其中 <span class="t-spar">枚举项列表</span> 是 <span class="t-spar">枚举项</span> 的逗号分隔列表<span class="t-rev-inl t-since-c99"><span>(允许尾随的逗号)</span> <span><span class="t-mark-rev t-since-c99">(C99 起)</span></span></span>,每个 <span class="t-spar">枚举项</span> 拥有形式:</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">枚举常量</span> <span class="t-spar">属性声明符序列</span><span class="t-mark">(可选)</span></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><span class="t-spar">枚举常量</span> <span class="t-spar">属性声明符序列</span><span class="t-mark">(可选)</span> <code><b>=</b></code> <span class="t-spar">常量表达式</span></td>
|
|
<td>(2)</td>
|
|
<td class="t-sdsc-nopad"></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">标识符</span>, <span class="t-spar">枚举常量</span></td>
|
|
<td>-</td>
|
|
<td>由此声明引入的标识符</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">常量表达式</span></td>
|
|
<td>-</td>
|
|
<td><a href="c-language-constant_expression.html">整数常量表达式</a>,其值可以以 <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">int</span></span></span> 类型的值表示</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">属性声明符序列</span></td>
|
|
<td>-</td>
|
|
<td><span class="t-mark-rev t-since-c23">(C23)</span>可选的<a href="c-language-attributes.html">属性列表</a>,
|
|
<ul>
|
|
<li>若出现在 <code><b>enum</b></code> 后则应用到整个枚举,</li>
|
|
<li>若出现在 <span class="t-spar">枚举常量</span> 后则应用到 <span class="t-spar">枚举项</span></li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<p>与<a href="c-language-struct.html">结构体</a>或<a href="c-language-union.html">联合体</a>一样,引入枚举类型和一或多个枚举常量的声明亦可声明一或多个该类型的对象,或从该类型派生的类型的对象。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw2">enum</span> color_t <span class="br0">{</span>RED, GREEN, BLUE<span class="br0">}</span> c <span class="sy1">=</span> RED, <span class="sy2">*</span>cp <span class="sy1">=</span> <span class="sy3">&</span>c<span class="sy4">;</span>
|
|
<span class="co1">// 引入类型 enum color_t</span>
|
|
<span class="co1">// 整数常量 RED 、 GREEN 、 BLUE </span>
|
|
<span class="co1">// 对象 c 拥有类型 enum color_t</span>
|
|
<span class="co1">// 对象 cp 的类型为指向 enum color_t 的指针</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>每个出现于枚举说明符体中的 <span class="t-spar">枚举常量</span> 会成为 <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">int</span></span></span> 类型的<a href="c-language-constant_expression.html">整数常量</a>,并处于包围它的作用域中,而且在凡要求整数常量处可用(例如,作为 case 标号或非 VLA 数组大小)。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw2">enum</span> color <span class="br0">{</span> RED, GREEN, BLUE <span class="br0">}</span> r <span class="sy1">=</span> RED<span class="sy4">;</span>
|
|
<span class="kw1">switch</span><span class="br0">(</span>r<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">case</span> RED<span class="sy4">:</span>
|
|
<a href="c-io-puts.html"><span class="kw836">puts</span></a><span class="br0">(</span><span class="st0">"red"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">break</span><span class="sy4">;</span>
|
|
<span class="kw1">case</span> GREEN<span class="sy4">:</span>
|
|
<a href="c-io-puts.html"><span class="kw836">puts</span></a><span class="br0">(</span><span class="st0">"green"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">break</span><span class="sy4">;</span>
|
|
<span class="kw1">case</span> BLUE<span class="sy4">:</span>
|
|
<a href="c-io-puts.html"><span class="kw836">puts</span></a><span class="br0">(</span><span class="st0">"blue"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw1">break</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>若 <span class="t-spar">枚举常量</span> 后随 <span class="t-spar">= 常量表达式</span> ,则其值为该常量表达式的值。若 <span class="t-spar">枚举常量</span> 没有后随 <span class="t-spar">= 常量表达式</span> ,则其值是比同一枚举中前一枚举项的值大一的值。首个枚举项(若它不用 <span class="t-spar">= 常量表达式</span> )的值是零。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw2">enum</span> Foo <span class="br0">{</span> A, B, C<span class="sy1">=</span><span class="nu0">10</span>, D, E<span class="sy1">=</span><span class="nu0">1</span>, F, G<span class="sy1">=</span>F<span class="sy2">+</span>C<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="co1">// A=0, B=1, C=10, D=11, E=1, F=2, G=12</span></pre></div>
|
|
</div>
|
|
<p>若使用 <span class="t-spar">标识符</span> ,则其自身成为标签<a href="c-language-name_space.html">命名空间</a>中枚举类型的名称,且需要使用关键词 enum (除非 typedef 到通常命名空间)。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw2">enum</span> color <span class="br0">{</span> RED, GREEN, BLUE <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw2">enum</span> color r <span class="sy1">=</span> RED<span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="co1">// color x = GREEN: // 错误: color 不在通常命名空间中</span>
|
|
<span class="kw1">typedef</span> <span class="kw2">enum</span> color color_t<span class="sy4">;</span>
|
|
color_t x <span class="sy1">=</span> GREEN<span class="sy4">;</span> <span class="co1">// OK</span></pre></div>
|
|
</div>
|
|
<p>每个枚举类型与如下之一<a href="c-language-types.html#.E5.85.BC.E5.AE.B9.E7.B1.BB.E5.9E.8B">兼容</a>: <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">char</span></span></span> 、有符号整数类型或无符号整数类型。对于任何枚举类型,哪一个类型是兼容的是实现定义的,但无论是那种类型,都必须有足以表示该枚举中所有枚举项的值。</p>
|
|
<p>枚举类型是整数类型,从而可以用于任何其他整数类型能用之处,包括<a href="c-language-conversion.html">隐式转换</a>和<a href="c-language-operator_arithmetic.html">算术运算符</a>。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw2">enum</span> <span class="br0">{</span> ONE <span class="sy1">=</span> <span class="nu0">1</span>, TWO <span class="br0">}</span> e<span class="sy4">;</span>
|
|
<span class="kw4">long</span> n <span class="sy1">=</span> ONE<span class="sy4">;</span> <span class="co1">// 提升</span>
|
|
<span class="kw4">double</span> d <span class="sy1">=</span> ONE<span class="sy4">;</span> <span class="co1">// 转换</span>
|
|
e <span class="sy1">=</span> <span class="nu16">1.2</span><span class="sy4">;</span> <span class="co1">// 转换,e 现在是 ONE</span>
|
|
e <span class="sy1">=</span> e <span class="sy2">+</span> <span class="nu0">1</span><span class="sy4">;</span> <span class="co1">// e 现在是 TWO</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>不同于 <a href="c-language-struct.html">struct</a> 或 <a href="c-language-union.html">union</a> , C 中没有 enum 的前置声明:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw2">enum</span> Color<span class="sy4">;</span> <span class="co1">// 错误:C 中无 enum 的前置声明</span>
|
|
<span class="kw2">enum</span> Color <span class="br0">{</span> RED, GREEN, BLUE <span class="br0">}</span><span class="sy4">;</span></pre></div>
|
|
</div>
|
|
<p>枚举允许以比 <span class="t-c"><span class="mw-geshi c source-c"><span class="co2">#define</span></span></span> 更加便利和结构化的方式生成具名常量;它们可见于调试器,遵循作用域规则,并且参与类型系统。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="co2">#define TEN 10</span>
|
|
<span class="kw1">struct</span> S <span class="br0">{</span> <span class="kw4">int</span> x <span class="sy4">:</span> TEN<span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// OK</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="kw2">enum</span> <span class="br0">{</span> TEN <span class="sy1">=</span> <span class="nu0">10</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">struct</span> S <span class="br0">{</span> <span class="kw4">int</span> x <span class="sy4">:</span> TEN<span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 也 OK</span></pre></div>
|
|
</div>
|
|
<p>另外,由于 C 中<a href="c-language-struct.html">结构体</a>或<a href="c-language-union.html">联合体</a>不建立其作用域,可以在前者的成员说明中引入枚举类型及其枚举常量,而之后其作用域与前者相同。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw1">struct</span> Element <span class="br0">{</span>
|
|
<span class="kw4">int</span> z<span class="sy4">;</span>
|
|
<span class="kw2">enum</span> State <span class="br0">{</span> SOLID, LIQUID, GAS, PLASMA <span class="br0">}</span> state<span class="sy4">;</span>
|
|
<span class="br0">}</span> oxygen <span class="sy1">=</span> <span class="br0">{</span> <span class="nu0">8</span>, GAS <span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="co1">// 类型 enum State 与其枚举常量于此保持可见,例如</span>
|
|
<span class="kw4">void</span> foo<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw2">enum</span> State e <span class="sy1">=</span> LIQUID<span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<a href="c-io-fprintf.html"><span class="kw851">printf</span></a><span class="br0">(</span><span class="st0">"%d %d %d "</span>, e, oxygen.<span class="me1">state</span>, PLASMA<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 打印 1 2 3</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<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="co2">#include <stdio.h></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="kw2">enum</span> TV <span class="br0">{</span> FOX <span class="sy1">=</span> <span class="nu0">11</span>, CNN <span class="sy1">=</span> <span class="nu0">25</span>, ESPN <span class="sy1">=</span> <span class="nu0">15</span>, HBO <span class="sy1">=</span> <span class="nu0">22</span>, MAX <span class="sy1">=</span> <span class="nu0">30</span>, NBC <span class="sy1">=</span> <span class="nu0">32</span> <span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<a href="c-io-fprintf.html"><span class="kw851">printf</span></a><span class="br0">(</span><span class="st0">"List of cable stations: <span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="c-io-fprintf.html"><span class="kw851">printf</span></a><span class="br0">(</span><span class="st0">" FOX: <span class="es1">\t</span>%2d<span class="es1">\n</span>"</span>, FOX<span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="c-io-fprintf.html"><span class="kw851">printf</span></a><span class="br0">(</span><span class="st0">" HBO: <span class="es1">\t</span>%2d<span class="es1">\n</span>"</span>, HBO<span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="c-io-fprintf.html"><span class="kw851">printf</span></a><span class="br0">(</span><span class="st0">" MAX: <span class="es1">\t</span>%2d<span class="es1">\n</span>"</span>, MAX<span class="br0">)</span><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">List of cable stations:
|
|
FOX: 11
|
|
HBO: 22
|
|
MAX: 30</pre></div>
|
|
</div>
|
|
</div>
|
|
<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.2.5/16 Types (p: 32)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.7.2.2 Enumeration specifiers (p: 84-85)</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.2.5/16 Types (p: 41)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.7.2.2 Enumeration specifiers (p: 117-118)</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.2.5/16 Types (p: 35)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.7.2.2 Enumeration specifiers (p: 105-106)</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.1.2.5 Types</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>3.5.2.2 Enumeration specifiers</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.85.B3.E9.94.AE.E8.AF.8D">关键词</span></h3>
|
|
<p><a href="c-keyword-enum.html"><tt>enum</tt></a></p>
|
|
<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>
|