goto
语句
来自 cppreference.cn
无条件地转移控制。
当无法使用其他语句将控制转移到所需位置时使用。
目录 |
[编辑] 语法
attr (可选) goto label ; |
|||||||||
[编辑] 解释
goto 语句将控制转移到 label 指定的位置。goto 语句必须与它引用的 label 在同一个函数中,它可以出现在标签之前或之后。
如果控制转移退出了任何自动变量的作用域(例如,通过向后跳转到此类变量声明之前的点,或者通过向前跳转到变量作用域所在的复合语句之外),则会为所有作用域已退出的变量调用析构函数,顺序与它们的构造顺序相反。
goto 语句不能将控制转移到控制流受限语句中,但可以将控制从控制流受限语句中转移出来(遵循上述关于作用域内自动变量的规则)。
如果控制转移进入任何自动变量的作用域(例如,通过向前跳转到声明语句之上),则程序是非良构的(无法编译),除非所有进入作用域的变量都具有以下类型
- 不带初始化器的标量类型
- 具有平凡默认构造函数和平凡析构函数且不带初始化器声明的类类型
- 上述类型之一的 cv 限定版本
- 上述类型之一的数组
(注意:相同的规则适用于所有形式的控制转移)
[编辑] 注解
在 C 编程语言中,goto 语句的限制较少,可以进入除变长数组或可变修改指针之外的任何变量的作用域。
[编辑] 关键字
[编辑] 示例
运行此代码
#include <iostream> struct Object { // non-trivial destructor ~Object() { std::cout << 'd'; } }; struct Trivial { double d1; double d2; }; // trivial ctor and dtor int main() { int a = 10; // loop using goto label: Object obj; std::cout << a << ' '; a -= 2; if (a != 0) goto label; // jumps out of scope of obj, calls obj destructor std::cout << '\n'; // goto can be used to efficiently leave a multi-level (nested) loops 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; // jumps into the scope of n and t [[maybe_unused]] int n; // no initializer [[maybe_unused]] Trivial t; // trivial ctor/dtor, no initializer // int x = 1; // error: has initializer // Object obj2; // error: non-trivial dtor label2: { Object obj3; goto label3; // jumps forward, out of scope of obj3 } label3: std::cout << '\n'; }
输出
10 d8 d6 d4 d2 (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) d d
[编辑] 参见
C 文档 关于 goto
|
[编辑] 外部链接
广受欢迎的 Edsger W. Dijkstra 论文,“Goto Considered Harmful” (最初发表于 "Letter to Communications of the ACM (CACM)", vol. 11 #3, March 1968, pp. 147-148.),概述了粗心使用此关键字可能引入的许多细微问题。 |