一、摘要(个人感悟)
goto用法在大学课堂里老师往往会一笔带过,同时很多书籍都建议“谨慎使用,或者根本不用,goto 语句使程序的静态结构和动态结构不一致,从而使程序难以理解,难以查错。但我参加工作后发现goto语句常被用于异常和错误处理。
很多人建议废除C++/C的goto语句,以绝后患。但实事求是地说,错误是程序员自己造成的,不是 goto 的过错。goto 语句至少有一处可显神通,它能从多重循环体中一下子跳到外面,用不着写很多次的break语句。例如:
for(......){
for(....){
for(.....){
// 如何冲出重重包围?
}
}
}
break; 只能跳出单层的循环,return 将整个函数都返回了,没法再继续了,显然也不行,所以我们想到了 goto 。如果是在陷入了很深层次的循环里想要跳出最外层的循环,用 goto 直接跳出却比用 break 一个循环一个循环地跳出要好得多。有人甚至形象比喻说:“就像楼房着火了,来不及从楼梯一级一级往下走,可从窗口跳出火坑。” 其实,你可以将 break 和 continue 理解成弱化了的 goto 语句。(这个例子来自百度百科goto语句)
介于以上原因(工作的需要和goto语句独特的优势),我打算总结一下goto的用法和应用场景,作为以后参考的笔记。
二、goto语句基本用法
goto语句可以使程序在没有任何条件的情况下跳转到指定的位置(本函数内跳转,不能跨函数跳转),所以goto语句又被称为是无条件跳转语句。
它的语法如下:
goto label;
//其它代码
label:
goto语句有两部分:goto和标签名
。标签的命名规则与变量的命名规则一样,它可以设置在 C 程序中 goto 语句的前面或者后面。
(1)使用goto语句实现向前跳转(if语句,但打印十次)
#include <stdio.h>
int main() {
int i = 0;
loop:
printf("i = %d\n", i);
i++;
if (i < 10)
{
goto loop;
}
return 0;
}
(2)使用goto语句实现向后跳转(for循环,但只打印一次)
#include <stdio.h>
int main() {
int i = 0;
i++;
for (i = 0;i < 10;i++)
{
goto only_one;
}
return 0;
only_one:
printf("i = %d\n", i);
}
如果你能看懂上面那两个例子,那恭喜你,你已经掌握goto语句的基本用法了。
三、goto语句的应用场景
1.从多重循环中直接跳出(当break和return无法达到你的需求时)
2. 出错时清除资源
当程序要分配和清除资源时(像内存、或处理字形、窗口、打印机),这种情形下用 goto 通常是为了复制代码或清除资源。若遇到这种情况,程序员就要掂量是 goto 的缺点更讨厌,还是复制代码那令人头痛的维护更讨厌,最后还是认为 goto 的缺点更可忍受。
四、goto语句使用建议
1.使用 goto 语句只能 goto 到同一函数内,而不能从一个函数里goto到另外一个函数里。
2.使用 goto 语句在同一函数内进行 goto 时,goto 的起点应是函数内一段小功能的结束处,goto 的目的label处应是函数内另外一段小功能的开始处。
3.应该避免向两个方向跳转。这样最容易导致"面条代码"。