130 lines
12 KiB
HTML
130 lines
12 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>goto 语句</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_goto skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">goto 语句</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">
|
|
<p>无条件转移控制流。</p>
|
|
<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 class="t-sdsc-nopad"><span class="t-spar">属性</span><span class="t-mark">(可选)</span> <code><b>goto</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>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>goto 语句将控制转移到<a href="cpp-language-statements.html#.E6.A0.87.E5.8F.B7">标号</a>所指定的位置。goto 语句必须与它所用的 <span class="t-spar">标号</span> 处于相同的函数中,它在标号的前后都可以出现。</p>
|
|
<p>如果控制的转移退出了任何自动变量的作用域(例如通过回跳到这种变量声明之前的位置,或向前跳出作为变量作用域的复合语句),那么为所有退出作用域的变量以其构造顺序的逆序调用析构函数。</p>
|
|
<p><code>goto</code> 不能将控制转移到 <a href="cpp-language-try_catch.html">try 块</a>或 catch 子句之内,但能将控制转移离开 try 块或 catch 子句(遵循上述有关作用域中的自动变量的规则)</p>
|
|
<p>如果控制被转移进入了任何自动变量的作用域(例如通过向前跳过声明语句),那么程序非良构(不能编译),除非进入作用域的所有变量拥有</p>
|
|
<div class="t-li1"><span class="t-li">1)</span> 标量类型,且声明不带初始化器</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 拥有平凡默认构造函数和析构函数的类类型,且声明不带初始化器</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 上述之一的 cv 限定版本</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 上述之一的数组</div>
|
|
<p>(注意:相同规则适用于控制转移的所有形式)</p>
|
|
<h3><span class="mw-headline" id=".E5.85.B3.E9.94.AE.E8.AF.8D">关键词</span></h3>
|
|
<p><a href="cpp-keyword-goto.html"><tt>goto</tt></a></p>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E6.84.8F">注意</span></h3>
|
|
<p>在 C 编程语言中,<code>goto</code> 语句的限制较少,并且能进入除变长数组或可变修改指针之外的任何变量的作用域。</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="kw1">struct</span> Object <span class="br0">{</span>
|
|
<span class="co1">// 非平凡析构函数</span>
|
|
~Object<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> <span class="st0">"d"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">struct</span> Trivial <span class="br0">{</span>
|
|
<span class="kw4">double</span> d1<span class="sy4">;</span>
|
|
<span class="kw4">double</span> d2<span class="sy4">;</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="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> a <span class="sy1">=</span> <span class="nu0">10</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 使用 goto 循环</span>
|
|
label<span class="sy4">:</span>
|
|
Object obj<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> a <span class="sy1"><<</span> <span class="st0">" "</span><span class="sy4">;</span>
|
|
a <span class="sy1">=</span> a <span class="sy2">-</span> <span class="nu0">2</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">if</span> <span class="br0">(</span>a <span class="sy3">!</span><span class="sy1">=</span> <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">goto</span> label<span class="sy4">;</span> <span class="co1">// 跳出 obj 的作用域,调用 obj 析构函数</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> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// goto 可用于简单地离开多层循环</span>
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">int</span> x <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> x <span class="sy1"><</span> <span class="nu0">3</span><span class="sy4">;</span> x<span class="sy2">++</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">int</span> y <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span> y <span class="sy1"><</span> <span class="nu0">3</span><span class="sy4">;</span> y<span class="sy2">++</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> <span class="st0">"("</span> <span class="sy1"><<</span> x <span class="sy1"><<</span> <span class="st0">";"</span> <span class="sy1"><<</span> y <span class="sy1"><<</span> <span class="st0">") "</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>x <span class="sy2">+</span> y <span class="sy1">>=</span> <span class="nu0">3</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">goto</span> endloop<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
endloop<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> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">goto</span> label2<span class="sy4">;</span> <span class="co1">// 跳入 n 和 t 的作用域</span>
|
|
<span class="kw4">int</span> n<span class="sy4">;</span> <span class="co1">// 没有初始化器</span>
|
|
Trivial t<span class="sy4">;</span> <span class="co1">// 平凡构造函数/析构函数,没有初始化器</span>
|
|
<span class="co1">// int x = 1; // 错误:有初始化器</span>
|
|
<span class="co1">// Object obj2; // 错误:没有平凡析构函数</span>
|
|
label2<span class="sy4">:</span>
|
|
|
|
<span class="br0">{</span>
|
|
Object obj3<span class="sy4">;</span>
|
|
<span class="kw1">goto</span> label3<span class="sy4">;</span> <span class="co1">// 向前跳,离开 obj3 的作用域</span>
|
|
<span class="br0">}</span>
|
|
label3<span class="sy4">:</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">10 d8 d6 d4 d2
|
|
(0;0)
|
|
(0;1)
|
|
(0;2)
|
|
(1;0)
|
|
(1;1)
|
|
(1;2)
|
|
|
|
dd</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.89.A9.E5.B1.95.E9.98.85.E8.AF.BB">扩展阅读</span></h3>
|
|
<p>Edsger W. Dijkstra 的著名文章<a rel="nofollow" class="external text" href="http://david.tribble.com/text/goto.html">《我认为 goto 有害》</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>
|