5. 流程控制(二):while循环、do-while循环、for循环、break与continue、循环嵌套
循环,说白了就是让计算机反复干同一件事。你让它打印100遍"Hello",它绝不会喊累。但写代码的人得想清楚:什么时候停?怎么停?停不下来怎么办?
我刚开始学C语言时,觉得循环不就是个"重复执行"嘛,有啥好讲的。直到有一次写串口接收程序,循环条件写反了,程序直接卡死,板子上的LED灯疯狂闪烁——嗯,从那以后我再也不敢小看循环了。
5.1 while循环:先判断,再执行
while循环的格式很简单:
while (条件表达式) {
// 循环体
// 当条件为真时反复执行
}
它的执行逻辑是:先判断条件,条件成立才进入循环体。如果一开始条件就不成立,循环体一次都不执行。
举个例子,我想计算1加到100:
#include <stdio.h>
int main() {
int i = 1;
int sum = 0;
while (i <= 100) {
sum += i;
i++;
}
printf("1+2+...+100 = %d\n", sum);
return 0;
}
这里有个关键点:循环变量i必须在循环体内更新。如果你忘了写i++,i永远等于1,条件永远成立——死循环就来了。
5.2 do-while循环:先执行,再判断
do-while和while的区别就一句话:do-while至少执行一次循环体。
do {
// 循环体
} while (条件表达式);
注意末尾有个分号,别漏了。我见过不少新手在这里栽跟头。
什么时候用do-while?比如你要从键盘读取数据,直到读到合法值为止。先读一次,如果不对再继续读:
int value;
do {
printf("请输入一个正数:");
scanf("%d", &value);
} while (value <= 0);
我个人习惯是:能确定至少执行一次的场景,用do-while;否则用while。这样代码意图更清晰。
5.3 for循环:最常用的循环
for循环把初始化、条件判断、循环变量更新都写在一行里:
for (初始化; 条件; 更新) {
// 循环体
}
还是1加到100的例子,用for写更紧凑:
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
三个部分都可以省略,但分号不能省。比如 for(;;) 就是死循环——我有时在嵌入式主循环里这么写,配合break跳出。
5.4 break与continue:循环的"刹车"和"跳过"
这两个关键字是循环里的控制利器。
- break:立即跳出整个循环,不再执行后续迭代。
- continue:跳过本次循环的剩余部分,直接进入下一次迭代。
看个例子:
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // i等于5时跳出循环
}
printf("%d ", i);
}
// 输出:1 2 3 4
for (int i = 1; i <= 10; i++) {
if (i == 5) {
continue; // i等于5时跳过本次,继续下一次
}
printf("%d ", i);
}
// 输出:1 2 3 4 6 7 8 9 10
我在项目中遇到过一个问题:用break跳出嵌套循环时,它只跳出最内层循环。如果你要跳出多层,要么用goto(不推荐),要么加一个标志变量。
5.5 循环嵌套:循环里面套循环
循环嵌套很常见,比如打印九九乘法表:
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d*%d=%2d ", j, i, i*j);
}
printf("\n");
}
外层循环控制行数,内层循环控制每行的列数。嵌套层数多了,时间复杂度会急剧上升——三层循环就是O(n³),数据量一大就卡死。
我记得有一次做图像处理,用了四层嵌套循环处理640×480的图像,结果一帧要算好几秒。后来优化成查表法,才降到毫秒级。所以嵌套循环虽好用,但别滥用。
5.6 三种循环的选择建议
| 循环类型 | 适用场景 | 执行次数 |
|---|---|---|
| while | 条件驱动,不确定次数 | 0次或多次 |
| do-while | 至少执行一次 | 1次或多次 |
| for | 已知循环次数 | 0次或多次 |
说白了,for循环用得最多,因为它结构清晰。while适合"等到某个条件成立就停"的场景。do-while用得最少,但某些场景下它是唯一选择。
5.7 知识体系图
下面这张图帮你理清本章的知识脉络:
5.8 避坑指南
- 死循环:循环条件永远为真,或者循环变量不更新。嵌入式开发中偶尔故意用死循环(比如主循环),但一定要有退出机制。
- 循环变量类型:用int没问题,但循环次数超过65535时注意别用short。我吃过这个亏。
- break只跳一层:嵌套循环里想跳出多层?用标志变量或者把循环封装成函数,用return。
- 分号别乱加:for后面加个分号,循环体就成空语句了。比如 for(i=0;i<10;i++); 后面的大括号只执行一次。
循环这东西,写多了自然就熟了。刚开始觉得绕,多写几个例子就通了。记住一点:循环是让计算机干活,不是让你自己干。能用循环解决的问题,别手写重复代码。
公众号:蓝海资料掘金营,微信deep3321