goto 语句
出自cppreference.com
無條件轉移控制流。
當使用其他語句不可能將控制轉移到所需位置時使用。
語法
屬性 (可選) goto 標號 ;
|
|||||||||
解釋
goto 語句將控制轉移到標號所指定的位置。goto 語句必須與它所用的標號 處於相同的函數中,它在標號的前後都可以出現。
如果控制的轉移退出了任何自動變量的作用域(例如通過回跳到這種變量聲明之前的位置,或向前跳出作為變量作用域的複合語句),那麼為所有退出作用域的變量以其構造順序的逆序調用析構函數。
goto 不能將控制轉移到有控制流限制的語句之內,但能將控制轉移離開有控制流限制的語句(遵循上述有關作用域中的自動變量的規則)
如果控制被轉移進入了任何自動變量的作用域(例如通過向前跳過聲明語句),那麼程序非良構,除非進入作用域的所有變量擁有以下類型:
- 標量類型,且聲明不帶初始化式
- 擁有平凡默認構造函數和析構函數的類類型,且聲明不帶初始化式
- 上述之一的 cv 限定版本
- 上述之一的數組
(注意:相同規則適用於控制轉移的所有形式)
註解
在 C 程式語言中,goto 語句的限制較少,並且能進入除變長數組或可變修改指針之外的任何變量的作用域。
關鍵詞
示例
運行此代碼
#include <iostream>
struct Object
{
// 非平凡析构函数
~Object() { std::cout << "d"; }
};
struct Trivial
{
double d1;
double d2;
}; // 平凡构造函数与析构函数
int main()
{
int a = 10;
// 使用 goto 循环
label:
Object obj;
std::cout << a << " ";
a -= 2;
if (a != 0)
goto label; // 跳出 obj 的作用域,调用 obj 析构函数
std::cout << '\n';
// goto 可用于简单地离开多层循环
for (int x = 0; x < 3; ++x)
for (int y = 0; y < 3; ++y)
{
std::cout << '(' << x << ',' << y << ") " << '\n';
if (x + y >= 3)
goto endloop;
}
endloop:
std::cout << '\n';
goto label2; // 跳入 n 和 t 的作用域
[[maybe_unused]] int n; // 没有初始化式
[[maybe_unused]] Trivial t; // 平凡构造函数/析构函数,没有初始化式
// int x = 1; // 错误:有初始化式
// Object obj2; // 错误:没有平凡析构函数
label2:
{
Object obj3;
goto label3; // 向前跳,离开 obj3 的作用域
}
label3:
std::cout << '\n';
}
輸出:
10 d8 d6 d4 d2
(0;0)
(0;1)
(0;2)
(1;0)
(1;1)
(1;2)
d
d
參閱
goto 的 C 文檔
|
外部連結
|
Edsger W. Dijkstra 的著名文章《我認為 goto 有害》(最初發表於《Letter to Communications of the ACM (CACM)》,卷 11, #3, 1968年三月出版),呈現了此關鍵詞的大意使用會引入的各種微妙問題的考察。 |