313 lines
21 KiB
HTML
313 lines
21 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>C 运算符优先级</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_operator_precedence skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">C 运算符优先级</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>下表列出 C 运算符的优先级和结合性。运算符从顶到底以降序列出。</p>
|
|
<table class="wikitable">
|
|
<tr>
|
|
<th style="text-align: left">优先级</th>
|
|
<th style="text-align: left">运算符</th>
|
|
<th style="text-align: left">描述</th>
|
|
<th style="text-align: left">结合性</th>
|
|
</tr>
|
|
<tr>
|
|
<th rowspan="6">1</th>
|
|
<td style="border-bottom-style: none"><code>++</code> <code>--</code></td>
|
|
<td style="border-bottom-style: none">后缀自增与自减</td>
|
|
<td style="vertical-align: top" rowspan="6">从左到右</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>()</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">函数调用</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>[]</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">数组下标</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>.</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">结构体与联合体成员访问</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>-></code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">结构体与联合体成员通过指针访问</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>(<i>type</i>){<i>list</i>}</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">复合字面量<span class="t-mark-rev t-since-c99">(C99)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<th rowspan="8">2</th>
|
|
<td style="border-bottom-style: none"><code>++</code> <code>--</code></td>
|
|
<td style="border-bottom-style: none">前缀自增与自减<sup id="cite_ref-1" class="reference"><a href="c-language-operator_precedence.html#cite_note-1">[注 1]</a></sup></td>
|
|
<td style="vertical-align: top" rowspan="8">从右到左</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>+</code> <code>-</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">一元加与减</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>!</code> <code>~</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">逻辑非与逐位非</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>(<i>type</i>)</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">转型</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>*</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">间接(解引用)</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>&</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">取址</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>sizeof</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">取大小<sup id="cite_ref-2" class="reference"><a href="c-language-operator_precedence.html#cite_note-2">[注 2]</a></sup></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>_Alignof</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">对齐要求<span class="t-mark-rev t-since-c11">(C11)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<th>3</th>
|
|
<td><code>*</code> <code>/</code> <code>%</code></td>
|
|
<td>乘法、除法及余数</td>
|
|
<td style="vertical-align: top" rowspan="11">从左到右</td>
|
|
</tr>
|
|
<tr>
|
|
<th>4</th>
|
|
<td><code>+</code> <code>-</code></td>
|
|
<td>加法及减法</td>
|
|
</tr>
|
|
<tr>
|
|
<th>5</th>
|
|
<td><code><<</code> <code>>></code></td>
|
|
<td>逐位左移及右移</td>
|
|
</tr>
|
|
<tr>
|
|
<th rowspan="2">6</th>
|
|
<td style="border-bottom-style: none"><code><</code> <code><=</code></td>
|
|
<td style="border-bottom-style: none">分别为 < 与 ≤ 的关系运算符</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-top-style: none"><code>></code> <code>>=</code></td>
|
|
<td style="border-top-style: none">分别为 > 与 ≥ 的关系运算符</td>
|
|
</tr>
|
|
<tr>
|
|
<th>7</th>
|
|
<td><code>==</code> <code>!=</code></td>
|
|
<td>分别为 = 与 ≠ 关系</td>
|
|
</tr>
|
|
<tr>
|
|
<th>8</th>
|
|
<td><code>&</code></td>
|
|
<td>逐位与</td>
|
|
</tr>
|
|
<tr>
|
|
<th>9</th>
|
|
<td><code>^</code></td>
|
|
<td>逐位异或(排除或)</td>
|
|
</tr>
|
|
<tr>
|
|
<th>10</th>
|
|
<td><code>|</code></td>
|
|
<td>逐位或(包含或)</td>
|
|
</tr>
|
|
<tr>
|
|
<th>11</th>
|
|
<td><code>&&</code></td>
|
|
<td>逻辑与</td>
|
|
</tr>
|
|
<tr>
|
|
<th>12</th>
|
|
<td><code>||</code></td>
|
|
<td>逻辑或</td>
|
|
</tr>
|
|
<tr>
|
|
<th>13</th>
|
|
<td><code>?:</code></td>
|
|
<td>三元条件<sup id="cite_ref-3" class="reference"><a href="c-language-operator_precedence.html#cite_note-3">[注 3]</a></sup></td>
|
|
<td style="vertical-align: top" rowspan="6">从右到左</td>
|
|
</tr>
|
|
<tr>
|
|
<th rowspan="5">14<sup id="cite_ref-4" class="reference"><a href="c-language-operator_precedence.html#cite_note-4">[注 4]</a></sup></th>
|
|
<td style="border-bottom-style: none"><code>=</code></td>
|
|
<td style="border-bottom-style: none">简单赋值</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>+=</code> <code>-=</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">以和及差赋值</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code>*=</code> <code>/=</code> <code>%=</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">以积、商及余数赋值</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-bottom-style: none; border-top-style: none"><code><<=</code> <code>>>=</code></td>
|
|
<td style="border-bottom-style: none; border-top-style: none">以逐位左移及右移赋值</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="border-top-style: none"><code>&=</code> <code>^=</code> <code>|=</code></td>
|
|
<td style="border-top-style: none">以逐位与、异或及或赋值</td>
|
|
</tr>
|
|
<tr>
|
|
<th>15</th>
|
|
<td><code>,</code></td>
|
|
<td>逗号</td>
|
|
<td>从左到右</td>
|
|
</tr>
|
|
</table>
|
|
<ol class="references">
|
|
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="c-language-operator_precedence.html#cite_ref-1">↑</a></span> <span class="reference-text">前缀 <code>++</code> 与 <code>--</code> 的运算数不能是转型。此规则在文法上禁止某些表达式本来也会在语义上非法的表达式。某些编译器忽略此规则并检测语义上的非法。</span></li>
|
|
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="c-language-operator_precedence.html#cite_ref-2">↑</a></span> <span class="reference-text"><code>sizeof</code> 的运算数不能是类型转型:表达式 <code>sizeof (int) * p</code> 无歧义地转译成 <code>(sizeof(int)) * p</code> ,而非 <code>sizeof((int)*p)</code> 。</span></li>
|
|
<li id="cite_note-3"><span class="mw-cite-backlink"><a href="c-language-operator_precedence.html#cite_ref-3">↑</a></span> <span class="reference-text">条件运算符中部( <code><b>?</b></code> 与 <code><b>:</b></code> 之间)的表达式分析为如同加括号:忽略其相对于 <code>?:</code> 的优先级。</span></li>
|
|
<li id="cite_note-4"><span class="mw-cite-backlink"><a href="c-language-operator_precedence.html#cite_ref-4">↑</a></span> <span class="reference-text">赋值运算符的左运算数必须是一元(第 2 级非转型)表达式。此规则在文法上禁止某些表达式本来也会在语义上非法的表达式。从而许多编译器忽略此规则并在语义上检测其非法。例如, <span class="t-c"><span class="mw-geshi c source-c">e <span class="sy1">=</span> a <span class="sy1"><</span> d <span class="sy4">?</span> a<span class="sy2">++</span> <span class="sy4">:</span> a <span class="sy1">=</span> d</span></span> 是因此规则而无法剖析的表达式。然而许多编译器忽略此规则并将它剖析成 <span class="t-c"><span class="mw-geshi c source-c">e <span class="sy1">=</span> <span class="br0">(</span> <span class="br0">(</span><span class="br0">(</span>a <span class="sy1"><</span> d<span class="br0">)</span> <span class="sy4">?</span> <span class="br0">(</span>a<span class="sy2">++</span><span class="br0">)</span> <span class="sy4">:</span> a<span class="br0">)</span> <span class="sy1">=</span> d <span class="br0">)</span></span></span> ,并给出错误,因为它在语义上非法。</span></li>
|
|
</ol>
|
|
<p>分析表达式时,列于上面表中某行的运算符,将比列于低于它的行中拥有较低优先级的任何运算符,更紧密地绑定到其参数(如同用括号)。例如,表达式 <span class="t-c"><span class="mw-geshi c source-c"><span class="sy2">*</span>p<span class="sy2">++</span></span></span> 被分析为 <span class="t-c"><span class="mw-geshi c source-c"><span class="sy2">*</span><span class="br0">(</span>p<span class="sy2">++</span><span class="br0">)</span></span></span> ,而非 <span class="t-c"><span class="mw-geshi c source-c"><span class="br0">(</span><span class="sy2">*</span>p<span class="br0">)</span><span class="sy2">++</span></span></span> 。</p>
|
|
<p>拥有相同优先级的运算符以其结合性的方向绑定到其参数。例如表达式 <span class="t-c"><span class="mw-geshi c source-c">a <span class="sy1">=</span> b <span class="sy1">=</span> c</span></span> 被分析为 <span class="t-c"><span class="mw-geshi c source-c">a <span class="sy1">=</span> <span class="br0">(</span>b <span class="sy1">=</span> c<span class="br0">)</span></span></span> 而非 <span class="t-c"><span class="mw-geshi c source-c"><span class="br0">(</span>a <span class="sy1">=</span> b<span class="br0">)</span> <span class="sy1">=</span> c</span></span> ,因为从右到左结合性。</p>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>优先级和结合性与<a href="c-language-eval_order.html">求值顺序</a>独立。</p>
|
|
<p>标准自身不指定优先级。它们派生自文法。</p>
|
|
<p>C++ 中,条件运算符拥有与赋值运算符相同的优先级,而前缀 <code>++</code> 与 <code>--</code> 及赋值运算符无关于其运算数的限制。</p>
|
|
<p>结合性规定对于一元运算符是冗余的,且只为完备而显示:一元前缀运算符始终从右到左结合( <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">sizeof</span> <span class="sy2">++*</span>p</span></span> 为 <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">sizeof</span><span class="br0">(</span><span class="sy2">++</span><span class="br0">(</span><span class="sy2">*</span>p<span class="br0">)</span><span class="br0">)</span></span></span> )而一元后缀运算符始终从左到右结合( <span class="t-c"><span class="mw-geshi c source-c">a<span class="br0">[</span><span class="nu0">1</span><span class="br0">]</span><span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span><span class="sy2">++</span></span></span> 为 <span class="t-c"><span class="mw-geshi c source-c"><span class="br0">(</span><span class="br0">(</span>a<span class="br0">[</span><span class="nu0">1</span><span class="br0">]</span><span class="br0">)</span><span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span><span class="br0">)</span><span class="sy2">++</span></span></span> )。注意结合性对成员访问运算符有意义,即使在它们与一元后缀运算符组合时: <span class="t-c"><span class="mw-geshi c source-c">a.<span class="me1">b</span><span class="sy2">++</span></span></span> 分析为 <span class="t-c"><span class="mw-geshi c source-c"><span class="br0">(</span>a.<span class="me1">b</span><span class="br0">)</span><span class="sy2">++</span></span></span> 而非 <span class="t-c"><span class="mw-geshi c source-c">a.<span class="br0">(</span>b<span class="sy2">++</span><span class="br0">)</span></span></span> 。</p>
|
|
<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>A.2.1 Expressions</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<div class="t-ref-std-c99">
|
|
<ul>
|
|
<li>C99 标准(ISO/IEC 9899:1999):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>A.2.1 Expressions</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<div class="t-ref-std-c89">
|
|
<ul>
|
|
<li>C89/C90 标准(ISO/IEC 9899:1990):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>A.1.2.1 Expressions</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<p>运行时运算符参数的<a href="c-language-eval_order.html">求值顺序</a>。</p>
|
|
<table class="wikitable">
|
|
<tr style="text-align:center">
|
|
<th colspan="7">常用运算符</th>
|
|
</tr>
|
|
<tr style="text-align:center">
|
|
<td><a href="c-language-operator_assignment.html">赋值</a></td>
|
|
<td><a href="c-language-operator_incdec.html">自增<br />
|
|
自减</a></td>
|
|
<td><a href="c-language-operator_arithmetic.html">算术</a></td>
|
|
<td><a href="c-language-operator_logical.html">逻辑</a></td>
|
|
<td><a href="c-language-operator_comparison.html">比较</a></td>
|
|
<td><a href="c-language-operator_member_access.html">成员<br />
|
|
访问</a></td>
|
|
<td><a href="c-language-operator_other.html">其他</a></td>
|
|
</tr>
|
|
<tr style="text-align:center">
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c">a <span class="sy1">=</span> b<br />
|
|
a <span class="sy2">+</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">-</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">*</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">/</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy2">%</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy3">&</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy3">|</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy3">^</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy1"><<=</span> b<br />
|
|
a <span class="sy1">>>=</span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c"><span class="sy2">++</span>a<br />
|
|
<span class="sy2">--</span>a<br />
|
|
a<span class="sy2">++</span><br />
|
|
a<span class="sy2">--</span></span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c"><span class="sy2">+</span>a<br />
|
|
<span class="sy2">-</span>a<br />
|
|
a <span class="sy2">+</span> b<br />
|
|
a <span class="sy2">-</span> b<br />
|
|
a <span class="sy2">*</span> b<br />
|
|
a <span class="sy2">/</span> b<br />
|
|
a <span class="sy2">%</span> b<br />
|
|
~a<br />
|
|
a <span class="sy3">&</span> b<br />
|
|
a <span class="sy3">|</span> b<br />
|
|
a <span class="sy3">^</span> b<br />
|
|
a <span class="sy1"><<</span> b<br />
|
|
a <span class="sy1">>></span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c"><span class="sy3">!</span>a<br />
|
|
a <span class="sy3">&&</span> b<br />
|
|
a <span class="sy3">||</span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c">a <span class="sy1">==</span> b<br />
|
|
a <span class="sy3">!</span><span class="sy1">=</span> b<br />
|
|
a <span class="sy1"><</span> b<br />
|
|
a <span class="sy1">></span> b<br />
|
|
a <span class="sy1"><=</span> b<br />
|
|
a <span class="sy1">>=</span> b</span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c">a<span class="br0">[</span>b<span class="br0">]</span><br />
|
|
<span class="sy2">*</span>a<br />
|
|
<span class="sy3">&</span>a<br />
|
|
a<span class="sy2">-</span><span class="sy1">></span>b<br />
|
|
a.<span class="me1">b</span></span></span></p>
|
|
</td>
|
|
<td>
|
|
<p><span class="t-c"><span class="mw-geshi c source-c">a<span class="br0">(</span>...<span class="br0">)</span><br />
|
|
a, b<br />
|
|
<span class="br0">(</span>type<span class="br0">)</span> a<br />
|
|
<span class="sy4">?</span> <span class="sy4">:</span><br />
|
|
<span class="kw4">sizeof</span><br />
|
|
_Alignof</span></span> <span class="t-mark-rev t-since-c11">(C11 起)</span></p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-dsc-begin"></table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|