欢迎光临散文网 会员登陆 & 注册

第 10 讲:跳转结构

2021-09-05 19:40 作者:SunnieShine  | 我要投稿

还记得前文学到的质数判断和嵌套循环吗?前文遇到了一个例子,我们尝试跳出循环,但发现知识不足以让我们在期间跳出循环的执行,所以我们在那个时候无能为力,好在这个思路并不会使得代码的逻辑变成错的,它仅仅涉及到代码执行的优化。

今天的内容,我们将会处理这些特殊的处理。我们一共要学习三种语句模式:“break 语句”、“continue 语句”和“标签 + goto 语句”模型。


break 语句:跳出循环

我们省略了一些代码,只关注于循环语句,和 break 语句。break 语句是单独有分号结尾的,否则它将只是一个关键字。

在执行循环的时候,如果发现它已经不是质数了,就没必要再往下执行后面的判断是否除尽的逻辑了,于是在这里就跳出循环,所以写在应当跳出循环的位置上。

很多小伙伴在初学这个语句的时候,以为它可以跳出 if 条件。请注意,break 语句是只跟包含它的这层循环有关,它仅能跳出一层循环。也就是说,如果有两个 while 循环,如果把 break 语句写在最里面,那么它也只能跳出最内层的循环,而靠外的这一层循环依旧会继续往下执行,比如原本的例子:

这个 break 语句只能让语句跳转到第 14 行继续执行,所以下方的 isPrime 的判断条件它照样要走。所以这么考虑起来,这个 break 语句的跳转逻辑是没有问题的。


continue 语句:执行下一次循环

要说 break 语句是跳出循环,那么和它写法类似的 continue 语句就不是这个行为了。continue 语句直接终结当前这一次循环的执行逻辑,直接跳转到循环的开头去判断条件(而 for 循环则跳转到增量处)。

上述示例给出了一个从 1 到 10 的循环。当循环执行的过程中发现 n 本身被 3 整除,就会自动跳转到 n++ 增量语句处执行,而不会遇到 printf("%d ", n); 语句。这个示例展示了如何输出不是 3 的整倍数的代码。

它和 break 语句不一样的地方在于,continue 不会退出代码,而是跳转到增量(for 循环)或条件(whiledo-while 循环)处执行。


goto 语句:跳转到任意的执行位置

goto 代替循环

最为灵活的语句非 goto 语句莫属,它可以跳转到程序的任意你想要到达的位置上去(当然,在 main 函数外面去是不可以的)。

考虑如下行为。如果我们没有循环的时候,我们可以尝试使用 goto 来达到循环的目的。

上述示例将会输出从 1 到 100 内的数字的和。当执行到条件满足时,将会自动统计结果,并跳转到 Loop 标签处(第 3 行)继续执行代码。直到条件不成立的时候,到 else 部分,输出结果,此时没有 goto 语句,所以会继续往下执行,而不会再返回上面了。

请注意,标签名称的定义依然满足标识符的命名规则(数字、字母、下划线的那些规矩),所以不要乱取名。而且,标签不能位于函数的外面。比如下面的这个示例,就会出现错误:

这段代码是会报错的,不是运行的时候出错,而是直接在运行和编译程序之前就会出现错误。


你叫它标签?

是的,在前文里,使用标识符规则加一个冒号的部分我们称为标签(Label)。标签并非任何执行语句,它没有意义,跟注释差不多。但和注释的区别在于,注释在运行的 exe 里不会出现,而标签你可能还会查到这个东西存在的影子。

标签可以控制程序运行的顺序和行为,比如上面正确的那一则例子,它可以控制语句形成一个循环,来达到模拟循环的效果。而且,在前文介绍的 switch 语句也大量使用到了标签。仔细回忆一下,switch 语句配合 case 语句使用,而 case 语句末尾就是用的冒号。是的,case 语句就是一个特殊的标签,它用于规定 switch 小括号里的表达式的结果的分情况处理行为。当都不成立的时候,语句将会跳转到 default 标签处执行。

但可以发现,它并不影响程序的真正运行规范(比如大括号并不会因为标签的行为而断开和分割开),所以请注意,像是 switch 语句或是上面的这样的例子里,我们不能在同一个范围里定义两个名字完全一样的变量。比如说

或是

两个例子里,变量在错误的代码处是完全可以看到第一行给出的变量的,所以在可以看到的地方重新定义这些变量是有语义冲突的。

不过,C 语言允许第 2 种情况的代码,意味着这个代码不会出错,但错误很隐蔽:在 case 3case 5 标签处各定义了一个 i 变量,而这两处的 i 和第 1 行定义的 i 并不是同一个变量,而是两个完全没有关系的变量,只是恰好这里同名了。

我们应尽量避免这种定义行为。


第 10 讲:跳转结构的评论 (共 条)

分享到微博请遵守国家法律