break、continue 和嵌套循环
上一课的循环都是老老实实地转完,直到条件不成立。可有时候事情做完了,没必要再转;有时候这一圈不想做,想直接跳到下一圈。这一课讲 break 和 continue,再讲循环里面再放一个循环。
1#include <stdio.h>2 3int main(void) {4 for (int n = 51; n <= 100; n++) {5 if (n % 7 == 0) {6 printf("找到了:%d\n", n);7 break;8 }9 }10 printf("不找了\n");11 return 0;12}
找到了:56 不找了
要找的是大于 50 的第一个 7 的倍数。找到 56 就够了,break 让循环马上结束,57 到 100 都不用再试。
break:马上结束循环
break 一跑,整个循环就结束了,程序跳到循环后面接着跑,循环体里 break 后面的代码也不会再跑。
break 常和 while (1) 一起用。1 永远是真,所以这个循环自己停不下来,**唯一的出口就是 break**。比如手里有 50 元,一件东西 12 元,能买几件:
1#include <stdio.h>2 3int main(void) {4 int budget = 50;5 int spent = 0;6 int items = 0;7 while (1) {8 if (spent + 12 > budget) {9 break;10 }11 spent += 12;12 items++;13 }14 printf("买了 %d 件,花了 %d 元\n", items, spent);15 return 0;16}
买了 4 件,花了 48 元
点单步,看第五圈:spent + 12 是 60,超过了 50,break 跳出循环,后面的 spent += 12; 没有跑。
小技巧: 写 while (1) 时,一定要确认 break 总有一天会跑到,不然就是死循环。
continue:跳过这一圈
continue 不结束循环,只是跳过这一圈剩下的代码,直接进入下一圈。在 for 里,下一圈之前照样会跑 i++。下面显示 1 到 10,跳过 3 的倍数:
1#include <stdio.h>2 3int main(void) {4 for (int i = 1; i <= 10; i++) {5 if (i % 3 == 0) {6 continue;7 }8 printf("%d ", i);9 }10 printf("\n");11 return 0;12}
1 2 4 5 7 8 10
这段程序显示几行?
1#include <stdio.h>2 3int main(void) {4 for (int i = 1; i <= 5; i++) {5 if (i == 3) {6 continue;7 }8 if (i == 5) {9 break;10 }11 printf("%d\n", i);12 }13 return 0;14}
i 是 1、2 时正常显示;是 3 时 continue 跳过了 printf;是 4 时显示;是 5 时 break 结束了循环,5 没有显示。显示的是 1、2、4,一共 3 行。
在 while 里用 continue 要小心:如果 i++ 写在循环体的最后,continue 会把它也跳过,i 就再也不变了,变成死循环。所以要在 continue 之前先让变量变好,或者改用 for。
循环里套循环
循环体里可以再放一个循环,叫嵌套循环。外面的循环每转一圈,里面的循环都要从头到尾转完一整遍:
1#include <stdio.h>2 3int main(void) {4 for (int i = 1; i <= 2; i++) {5 for (int j = 1; j <= 3; j++) {6 printf("i = %d, j = %d\n", i, j);7 }8 }9 return 0;10}
i = 1, j = 1 i = 1, j = 2 i = 1, j = 3 i = 2, j = 1 i = 2, j = 2 i = 2, j = 3
外面 2 圈,里面每次 3 圈,一共 6 行。点单步,看 j 怎么一次次地从 1 重新开始。
用嵌套循环可以打出一张乘法表。外面的 i 管第几行,里面的 j 管这一行的第几个,j 只走到 i:
1#include <stdio.h>2 3int main(void) {4 for (int i = 1; i <= 5; i++) {5 for (int j = 1; j <= i; j++) {6 printf("%d×%d=%-4d", j, i, i * j);7 }8 printf("\n");9 }10 return 0;11}
1×1=1 1×2=2 2×2=4 1×3=3 2×3=6 3×3=9 1×4=4 2×4=8 3×4=12 4×4=16 1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
注意 printf("\n") 的位置:它在里面的循环外面、外面的循环里面,所以每一行结束时换一次行。
画三角形
同样的办法,把数换成星号,就能画出图形。第 row 行打 row 个 *:
1#include <stdio.h>2 3int main(void) {4 int height = 4;5 for (int row = 1; row <= height; row++) {6 for (int k = 1; k <= row; k++) {7 printf("*");8 }9 printf("\n");10 }11 return 0;12}
* ** *** ****
画图形时,先想清楚每一行要打几个字符,和行号是什么关系,再写里面那个循环的条件。
break 只跳出一层
在嵌套循环里,break 只结束它所在的那一层循环,外面的循环照样转:
1#include <stdio.h>2 3int main(void) {4 for (int i = 1; i <= 3; i++) {5 for (int j = 1; j <= 3; j++) {6 if (j == 2) {7 break;8 }9 printf("i = %d, j = %d\n", i, j);10 }11 }12 return 0;13}
i = 1, j = 1 i = 2, j = 1 i = 3, j = 1
想一找到就把两层都结束,可以用一个变量做记号:里面找到了,先把记号设成 1 再 break;外面每一圈结束时看看记号,是 1 就也 break。下面找第一对乘起来等于 12 的数:
1#include <stdio.h>2 3int main(void) {4 int found = 0;5 for (int i = 1; i <= 9; i++) {6 for (int j = 1; j <= 9; j++) {7 if (i * j == 12) {8 printf("%d × %d = 12\n", i, j);9 found = 1;10 break;11 }12 }13 if (found) {14 break;15 }16 }17 return 0;18}
2 × 6 = 12
把外面那个 if (found) 删掉再运行,看看会多出哪几行。
变量在哪里能用
在花括号里声明的变量,只在这对花括号里能用;在 for 的括号里声明的 i,只在这个循环里能用。循环结束后再用它,编译不过:
1#include <stdio.h>2 3int main(void) {4 for (int i = 1; i <= 3; i++) {5 int square = i * i;6 printf("%d\n", square);7 }8 printf("%d\n", i);9 return 0;10}
main.c: In function 'main':
main.c:8:20: error: 'i' undeclared (first use in this function)
8 | printf("%d\n", i);
| ^
main.c:8:20: note: each undeclared identifier is reported only once for each function it appears in编译器说 'i' undeclared,也就是 i 没有声明:在第 8 行,i 已经不存在了。square 也一样,而且它每一圈都是新的,上一圈的值留不下来。循环结束后还要用的变量,要在循环前面声明,比如把 int i; 写在 for 之前,再写 for (i = 1; i <= 3; i++)。变量能用的范围叫作用域,第 9 课再细讲。
练一练
写好代码,点检查。提示随便看,实在想不出来再看答案。
第一个平方超过 200 的数
✓从 1 开始一个一个地试,找到第一个平方大于 200 的数,显示它(15),然后用 break 结束循环。
15
1#include <stdio.h>2 3int main(void) {4 for (int n = 1; n <= 100; n++) {5 6 }7 return 0;8}
跳过 4 的倍数
✓把 1 到 20 加起来,但跳过 4 的倍数,用 continue 写。显示结果 150。
150
1#include <stdio.h>2 3int main(void) {4 int total = 0;5 for (int i = 1; i <= 20; i++) {6 7 total += i;8 }9 printf("%d\n", total);10 return 0;11}
倒过来的三角形
✓用嵌套循环显示一个倒过来的三角形:第一行 4 个 *,每行少一个,最后一行 1 个。
**** *** ** *
1#include <stdio.h>2 3int main(void) {4 int height = 4;5 6 return 0;7}
这一课学会了
break马上结束循环;while (1)只能靠break出来,要确认它一定会跑到。continue跳过这一圈剩下的代码,进入下一圈;在while里小心别把让变量变的那一行也跳过了。- 嵌套循环:外面每转一圈,里面都从头转完一整遍;乘法表和三角形都是这样打出来的。
- 嵌套循环里的
break只跳出一层;要两层都结束,用一个记号变量。 - 在花括号里或
for的括号里声明的变量,出了那个范围就不能用了。