7.8 goto语句
goto语句在C中仍然可用。但是C没有goto语句C程序也能运行良好。Kernighan和Ritchie提到goto语句“已被滥用”,并建议“谨慎使用,
或者根本不用”。
goto语句有两部分:goto和标签名。标签的命名遵循变量命名规则。例如:
goto part2;
要让这条语句正常工作,函数还必须包含另一条标为part2的语句,该语句以标签名后紧跟一个冒号开始:
part2:printf( "Refined analysis:\n" );
7.8.1 避免使用goto
原则上,根本不用在C程序中使用goto语句。FORTRAN或BASIC(goto这两种语言而言都必不可少),可能还会依赖goto来编程。
使用goto的常见情况,然后再介绍C的解决方案。
*处理包含多条语句的if语句:
if( size > 12 )
goto a;
goto b;
a: cost = cost * 1.05;
flag = 2;
b: bill = cost * flag;
对于以前的BASIC和FORTRAN,只有直接跟在if条件后面的一条语句才属于if,不能使用块或复合语句。我们把以上模式转换成等价的C代码,标准C用复合语句或块来处理这种情况:
if( size > 12 ){
cost = cost * 1.05;
flag = 2;
}
bill = cost * flag;
*二选一
if( ibex > 14 )
goto a;
sheds = 2;
goto b;
a: sheds = 3;
b: help = 2 * sheds;
C通过if else表达二选一更清楚:
if( ibex > 14 )
sheds = 3;
else
sheds = 2;
help = 2 * sheds;
实际上,新版的BASIC和FORTRAN已经把else纳入新的语法中。
*创建不确定循环:
readin: scanf( "%d", &score );
if( score < 0 )
goto stage2;
lots of statements
goto readin;
state2: more stuff;
C用while循环代替:
scanf( "%d", &score );
while( score >= 0 ){
lots of statements
scanf( "%d", &score );
}
more stuff;
*跳转至循环尾部,并开始下一轮迭代,C使用continue语句代替。
*跳出循环。C使用break语句。实际上,break和continue是goto的特殊形式。使用break和continue的好处是:其名称已经表明它们的用法,而且这些语句不使用标签,所有不用担心把标签放错位置导致的危险。
*胡乱跳转至程序的不同部分。简而言之,不要这样做!
但是,C程序员可以接受一种goto的用法---出现问题时从一组嵌套循环中跳出(一条break语句只能跳出当前循环):
while( funct > 0 ){
for( j = 1; j <= 50; j++ ){
其他语句
if( 问题 )
goto help;
其他语句
}
其他语句
}
其他语句
help:语句
过度地使用goto语句,会让程序错综复杂。如果不熟悉goto语句,就不要使用它。如果已经习惯使用goto语句,试着改掉这个毛病。讽刺地是,虽然C根本不需要goto,但是它的goto比其他语言的goto好用,因为C允许在标签中使用描述性的单词而不是数字。
标签语句可以出现在goto的前面或后面。
形式:
goto label;
...
label : statement
示例:
top : ch = getchar();
...
if( ch != 'y' )
goto top;
7.9 关键概念
智能的一个方面是,根据情况做出相应的相应。所以,选择语句是开发具有智能行为程序的基础。
要记住一个通用原则,如果要测试两个条件,应该使用逻辑运算符把两个完整的测试表达式组合起来。