Kodewick
第 6 课,共 30 课目录

循环

第 6 课,共 30 课 · 第 1 部分 · 起步 · 约 15 分钟

要把同样的事做很多遍,不用把代码抄很多遍,写一个循环就行。循环是单步最好看的地方:点单步,能看着程序一圈一圈地转,变量一次一次地变。

main.c
1#include <stdio.h>2 3int main(void) {4    int n = 3;5    while (n > 0) {6        printf("%d\n", n);7        n--;8    }9    printf("出发!\n");10    return 0;11}
输出
3
2
1
出发!

while 循环

while 先看括号里的条件:成立,就跑一遍循环体,然后回到开头再看条件;不成立,就跳过循环体,接着往下跑。

一个能停下来的循环,通常有三样东西:

部分上面的例子里
开始前,给变量一个值int n = 3;
每一圈先检查的条件n > 0
循环体里让变量变一变n--;
main.c
1#include <stdio.h>2 3int main(void) {4    int day = 1;5    while (day <= 5) {6        printf("第 %d 天\n", day);7        day++;8    }9    printf("循环结束时 day 是 %d\n", day);10    return 0;11}
输出
第 1 天
第 2 天
第 3 天
第 4 天
第 5 天
循环结束时 day 是 6

注意最后一行:循环停下时,day 已经是 6 了,正是 day <= 5 不成立的那一刻。

先猜一猜

这段程序显示几行?

1#include <stdio.h>2 3int main(void) {4    int n = 1;5    while (n < 10) {6        printf("%d\n", n);7        n = n * 2;8    }9    return 0;10}

累加:一边转一边加

循环最常见的用法之一是把很多数加起来。先准备一个从 0 开始的变量,每转一圈把一个数加进去:

main.c
1#include <stdio.h>2 3int main(void) {4    int total = 0;5    int i = 1;6    while (i <= 10) {7        total += i;8        i++;9    }10    printf("1 到 10 的和是 %d\n", total);11    return 0;12}
输出
1 到 10 的和是 55

点单步,盯着变量 total:0、1、3、6、10……每一圈多加一个 i。

计数:数一数有几个

计数也一样:准备一个从 0 开始的变量,遇到符合条件的就加 1。下面数一数 1 到 30 里有几个 3 的倍数:

main.c
1#include <stdio.h>2 3int main(void) {4    int count = 0;5    int i = 1;6    while (i <= 30) {7        if (i % 3 == 0) {8            count++;9        }10        i++;11    }12    printf("有 %d 个\n", count);13    return 0;14}
输出
有 10 个

有时候不知道要转几圈,只知道什么时候停。比如每个月存 300 元,存到 2000 元要几个月?

main.c
1#include <stdio.h>2 3int main(void) {4    int balance = 0;5    int months = 0;6    while (balance < 2000) {7        balance += 300;8        months++;9    }10    printf("%d 个月后有 %d 元\n", months, balance);11    return 0;12}
输出
7 个月后有 2100 元

for 循环

「从几数到几」的循环太常见了,C 有一种更紧凑的写法:for。它把开始、条件、变化三样东西放在同一行,用分号隔开:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int i = 1; i <= 5; i++) {5        printf("第 %d 圈\n", i);6    }7    printf("转完了\n");8    return 0;9}
输出
第 1 圈
第 2 圈
第 3 圈
第 4 圈
第 5 圈
转完了
部分什么时候跑
int i = 1只在最开始跑一次
i <= 5每一圈开始前检查,不成立就结束
i++每一圈循环体跑完以后

这里的 i 是在 for 里声明的,只能在这个循环里用,循环结束它就没有了。

第三部分不一定是 i++,可以一次加 10,也可以往下数:

main.c
1#include <stdio.h>2 3int main(void) {4    for (int c = 0; c <= 40; c += 10) {5        printf("%d 摄氏度 = %d 华氏度\n", c, c * 9 / 5 + 32);6    }7    for (int i = 10; i > 0; i -= 3) {8        printf("%d\n", i);9    }10    return 0;11}
输出
0 摄氏度 = 32 华氏度
10 摄氏度 = 50 华氏度
20 摄氏度 = 68 华氏度
30 摄氏度 = 86 华氏度
40 摄氏度 = 104 华氏度
10
7
4
1

小技巧: 知道要转几圈,用 for;只知道什么时候停(比如存够钱为止),用 while。两种都能写,挑读起来清楚的那种。

do while:先做再问

while 先检查条件,条件一开始就不成立,循环体一次都不跑。do while 反过来:先跑一遍循环体,再检查条件,所以至少跑一次。注意最后的 while (...) 后面有分号。

main.c
1#include <stdio.h>2 3int main(void) {4    int n = 10;5    while (n < 5) {6        printf("while 跑了\n");7    }8    do {9        printf("do while 跑了\n");10    } while (n < 5);11    return 0;12}
输出
do while 跑了

两个循环的条件一样,n < 5 都不成立。while 的循环体一次也没跑;do while 跑了一次,然后才发现该停了。

死循环

条件永远成立,循环就永远停不下来,这叫死循环。最常见的原因是忘了让变量变:

1int n = 3;2while (n > 0) {3    printf("%d\n", n);4}

循环体里没有 n--,n 一直是 3,n > 0 一直成立,程序会不停地显示 3。在终端里,只能按 Ctrl+C 强行停掉它。在这个页面上,程序跑了太多步还没结束时,会被停下来,并告诉你。

遇到程序停不下来,先看三样东西:条件写对了没有?循环体里有没有让变量变?变的方向对不对(该加的写成了减,就永远到不了)?

练一练

写好代码,点检查。提示随便看,实在想不出来再看答案。

练习 1

1 乘到 5

用一个循环算出 1 × 2 × 3 × 4 × 5,显示结果 120。

要显示
120
exercise1.c
1#include <stdio.h>2 3int main(void) {4    int product = 1;5 6    return 0;7}
输出
点「运行」或按 Ctrl+Enter
练习 2

价目表

一杯咖啡 12 元。用 for 循环显示买 1 到 4 杯的价钱,每行一个,格式和下面一样。

要显示
1 杯:12 元
2 杯:24 元
3 杯:36 元
4 杯:48 元
exercise2.c
1#include <stdio.h>2 3int main(void) {4    int price = 12;5 6    return 0;7}
输出
点「运行」或按 Ctrl+Enter
练习 3

走到一万步

小林每走一圈操场是 450 步。用 while 算出他至少要走几圈,才能走满 10000 步,显示 23 圈,10350 步。

要显示
23 圈,10350 步
exercise3.c
1#include <stdio.h>2 3int main(void) {4    int steps = 0;5    int laps = 0;6 7    return 0;8}
输出
点「运行」或按 Ctrl+Enter

这一课学会了

  • while 先检查条件,成立就跑一遍循环体,再回来检查;一开始就不成立,一次都不跑。
  • for (开始; 条件; 变化) 把三样东西写在一行,适合「从几数到几」。
  • do while 先跑再检查,循环体至少跑一次;最后有分号。
  • 累加和计数:先准备一个从 0 开始的变量,每一圈往里加。
  • 条件永远成立就是死循环;检查条件、检查循环体里有没有让变量往对的方向变。