提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
goto语句在大多数由程序员直接完成的高级程序设计任务中都没什么用,但是在由别的程序生成的C++代码中非常重要。例如,goto可能会出现在一个由解析生成器生成的解析程序中。
一、标签作用域
标签的作用域是标签所处的函数。这意味着你能用goto从块的范围跳进跳出,唯一的限制
是不能跳过初始化器
或者跳入到异常处理程序中
。
二、使用
1.普通用法
根据条件判断来选择跳转时机。
int a = 1;
if(a == 1)
goto exit;
cout << "a != 1" << endl;
exit:
cout << "a == 1" << endl;
注意:无论跳不跳转,exit后面的代码最终都会执行,goto跳过的是exit前的代码。
2.跳出循环
goto可以直接跳出多层循环,break只能跳出离自己最近的那个循环。
int a = 1;
for (int i = 0; i < 10; ++i) {
cout << "i == " << i << endl;
for (int j = 0; j < 10; ++j) {
cout << "j == " << j << endl;
if (j == 3)
goto exit;
}
}
cout << "a != 1" << endl;
exit:
cout << "a == 1" << endl;
3.跳入语句
goto可以跳入标签作用域内几乎任何语句,比如if语句。一般if语句会判断条件来确定是否执行,goto不用判断if条件也能跳转,你要确定这么做是不是有意义。
int a = 1;
for (int i = 0; i < 10; ++i) {
cout << "i == " << i << endl;
for (int j = 0; j < 10; ++j) {
cout << "j == " << j << endl;
if (j == 4)
goto exit2;
}
}
cout << "a != 1" << endl;
exit1:
cout << "a == 1" << endl;
if (a != 0) {
exit2:
cout << "a != 0" << endl;
goto exit1;
}
注意:上面的程序段会陷入 死循环!
三、注意
1.初始化错误
goto代码之后不能存在初始化语句,否则编译不通过。
int a = 1;
for (int i = 0; i < 10; ++i) {
cout << "i == " << i << endl;
for (int j = 0; j < 10; ++j) {
cout << "j == " << j << endl;
if (j == 3)
goto exit;
}
}
int b = 1;//初始化语句,编译报错
cout << "a != 1" << endl;
exit:
cout << "a == 1" << endl;
这段代码编译不通过,具体报错为:
/tmp/tmp.pGCVxb1Mvn/main.cpp: In function 鈥�void test_goto()鈥�:
/tmp/tmp.pGCVxb1Mvn/main.cpp:55:5: error: jump to label 鈥�exit鈥�
55 | exit:
| ^~~~
/tmp/tmp.pGCVxb1Mvn/main.cpp:50:22: note: from here
50 | goto exit;
| ^~~~
/tmp/tmp.pGCVxb1Mvn/main.cpp:53:9: note: `crosses initialization` of 鈥�int b鈥�
53 | int b = 1;
| ^
2.异常错误
goto语句的标签不能放在异常处理程序中,导致编译不通过。
int a = 1;
for (int i = 0; i < 10; ++i) {
cout << "i == " << i << endl;
for (int j = 0; j < 10; ++j) {
cout << "j == " << j << endl;
if (j == 4)
goto exit2;
}
}
cout << "a != 1" << endl;
exit1:
cout << "a == 1" << endl;
try {
exit2:
cout << "try" << endl;
} catch (...) {
}
这段代码编译不通过,具体报错为:
/tmp/tmp.pGCVxb1Mvn/main.cpp: In function 鈥�void test_goto()鈥�:
/tmp/tmp.pGCVxb1Mvn/main.cpp:61:9: error: jump to label 鈥�exit2鈥�
61 | exit2:
| ^~~~~
/tmp/tmp.pGCVxb1Mvn/main.cpp:52:22: note: from here
52 | goto exit2;
| ^~~~~
/tmp/tmp.pGCVxb1Mvn/main.cpp:61:9: note: `enters 鈥�try鈥� block`
61 | exit2:
| ^~~~~
gmake[3]: *** [CMakeFiles/Vector.dir/build.make:76: CMakeFiles/Vector.dir/main.cpp.o] Error 1
gmake[2]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Vector.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:90: CMakeFiles/Vector.dir/rule] Error 2
gmake: *** [Makefile:124: Vector] Error 2
总结
1、应该来说跳出循环可能是最有用的功能了
2、goto可以通过逻辑语句替代