有些逻辑需要反复执行。比如连续打印多次、累加一百个数字,如果手动复制粘贴代码,显然很低效。用好循环之后,打印三行和打印一千行,代码体量相差无几,区别仅仅在于是否使用循环结构。C 语言提供三种循环:for、while、do-while。
for 循环:三个动作一屏装下
for 把三件事捆在一起:初始化计数器、检查有没有到头、推进计数器。典型的例子是打印 0 到 9:
int i;
for (i = 0; i < 10; i++) {
printf("%d\n", i);
}拆开看执行顺序:
① i = 0 ,初始化,只跑这一次
② i < 10 ,检查条件,不成立就退出循环
③ printf ,执行循环体
④ i++ ,计数器加一,回到 ②所以这段打印 10 个数(0 到 9)。i 就是循环里最常见的迭代器变量。也可以一口气在 for 里声明(新版标准支持):for (int i = 0; i < 10; i++)。
用 for 遍历数组
for 最常见的搭档是数组,拿迭代器当下标,把数组从头走到尾:
int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = 0;
int i;
for (i = 0; i < 10; i++) {
sum += array[i];
}
printf("数组的和是 %d\n", sum); // 55把 += 换成 *=,就是求阶乘的雏形,学完这篇可以顺手练一练 10! 是多少。
while 循环:只写条件
while 比 for 功能少一截:它只有条件,初始化和推进都得自己写在循环体里:
int n = 0;
while (n < 10) {
n++;
}只要 n < 10 成立就一直转。如果你忘了让 n 变化,这个循环就永远出不去。
#include <stdio.h>
int main(void) {
int i = 0;
while (i <= 5) { // 输出 1 到 6
printf("%d ", i + 1);
i++; // 让条件有机会结束
}
printf("\n");
return 0;
}do-while 循环:先干一次再检查
do-while 是先执行再判断,所以循环体至少会跑一次。适合先让用户输入,再判断合不合格这种场景:
int n;
do {
printf("输入一个正数:");
scanf("%d", &n);
} while (n <= 0);注意结尾有分号 ;。三种循环怎么选:数清楚做几次用 for,次数不定但可能一次不做用 while,必须至少做一次用 do-while。
while 循环流程:先判断条件,为真进入循环体,跑完回到条件再判断
无限循环
条件永远为真的循环就是无限循环,通常是写错,但有些场合故意这么写:
while (1) { /* 永远转 */ }
for (;;) { /* 永远转 */ }配合下面两个刹车语句,可以做出一直等,等到了就停的效果。
break 与 continue:两个刹车
所有循环类型都通用的两个指令:
break;,立刻结束整个循环。continue;,跳过本次循环剩余语句,直接进下一轮。
break 的经典用法:明明写的是无限循环,数到 10 就停:
int n = 0;
while (1) {
n++;
if (n == 10) {
break; // 到这里就跳出循环
}
}continue 的经典用法:只打印偶数。注意 continue 跳过了打印,奇数永远轮不到,但 n++ 在 continue 之前执行,所以不会卡死:
int n = 0;
while (n < 10) {
n++;
if (n % 2 == 1) {
continue; // 回到 while 开头重新判断
}
printf("偶数:%d\n", n); // 只有 n 为偶数才会走到这
}嵌套循环
循环里套循环,外层每走一步,内层完整跑一圈。两个 for 就能打出乘法口诀表:
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
printf("%d×%d=%-2d ", j, i, j * i);
}
printf("\n");
}脑内推一遍:i=1 时内层只跑 j=1;i=2 时内层跑 j=1、j=2;于是每行长度刚好等于行号。
死循环排查
程序运行卡死,绝大多数情况都是死循环。排查可以遵循这个思路:循环条件能否发生变化?循环体内有没有代码推动条件走向终止?小心 continue 意外跳过计数器更新语句。另外 for(;;)、while(1) 这类无限循环,如果缺少对应的 break,也是非常常见的失误。