### C语言关键字浅析系列 ###
### ISO/ANSI C 关键字 ###
如果你对BASIC和FORTRAN很熟悉,那么对goto关键字应该会很熟悉
字面意思,goto应该指的是程序跳转到指定的地方去,听上去似乎还略有一番汇编语言的特点
然而如果你有了一定量的C语言编程经验就会发现,现在我们几乎不用goto这种格式,可能比auto用的还少
goto的作用是:
使程序跳转到标签处继续执行。
1、goto语句的结构
goto语句由两部分组成,一部分是goto,另一部分是标签:
/* 只将一位正整数转换为字符型 */
if (i >= 0 && i < 10)
goto a;
goto b;
a: return ('0' + i); /* i是正整数时跳转到这里执行 */
b: return '#'; /* 否则执行下一句goto,到这里开始执行 */
也许你会考虑如果跳转到a,而a不是这样的返回语句呢,下面这个例子可能就更恰当一点了:
/* 只将一位正整数转换为字符型 */
char j;
if (i >= 10)
goto a;
goto b;
a: j %= 10; /* 如果跳转到此处,执行完毕后将继续往下执行,相当于这只是个加工过程 */
b: j = '0' + i;
2、请弃用goto
但是,仅用C语言的if-else选择结构以及能很直观和简练的完成这个过程了:
/* 只将一位正整数转换为字符型,同样的效果,但无需到处goto了 */
char j;
if (j >= 10) j %= 10;
j = '0' + i;
如果把if-else结构换成goto实现,习惯了C语言风格的人可能很抓狂:
/* goto实现 */
if (i > 10)
goto J_EQUALS_ZERO;
j = 1;
goto J_EQUALS_ONE;
J_EQUALS_ZERO: j = 0;
J_EQUALS_ONE: i--;
/* A C Programmer:“上面这都什么乱七八糟的,不就这意思么” */
if (i > 10)
j = 1;
else
j = 0;
i++;
如果一个C程序员一个汇编程序员和一个喜欢写goto的魔鬼C程序员(如果恰好你喜欢在C里面用goto请这样读魔tian鬼shi)
坐在一个咖啡桌慢品下午茶,当他们聊到怎么优雅地写一个循环结构时,我想魔鬼C大佬会和汇编大佬相拥而泣然后被C程序员打一顿:
/* 大佬们在算1-100的和 */
int i = 0, sum = 0;
loop: i++;
if (i > 100)
goto Out; /* 写到这里汇编大佬笑了 */
sum += i;
goto loop;
Out: printf("Summary of 1-100 is %d\n", sum);
/* C大佬愤怒地拿了双杀并修改了代码,还把左括号前置了以致敬K&R风格,以此示威 */
int i = 1, sum = 0;
while (i <= 100){
sum += i;
i++;
}
printf("Summary of 1-100 is %d\n", sum)
至于循环和选择结构的嵌套.....我都不想举例了,有兴趣自己写吧
3、弃用不等于没用!
有些时候我们会略带惋惜地说,其实break和continue就是一种特殊的goto,你们把goto封杀地太惨了
确实,这两个关键字很像是在隐式地使用goto,但其实goto有一种潜力经常被忽视,却能起到画龙点睛逆袭break和continue的作用
/* 多重循环 */
while (1)
{
for (初始化1;测试1;更新1)
{
for (初始化2;测试2;更新2)
{
……
/* 如果此处出现了报错、故障,使用break和continue都只能跳出一层循环 */
if (报错检测)
goto Rescue; /* 使用goto直接跳出多层循环,可以无视层数,达到救济效果 */
……
}
}
}
Rescue: printf("安全跳出多层循环体了\n");
所以goto就是这样一个勿忘勿念的关键字,无论被吐槽多少次,它还是有自己存在的意义的
——参考《C Primer Plus第五版》
相关文章: