Kodewick
第 7 课,共 30 课目录

循环

第 7 课,共 30 课 · 第 2 部分 · 流程和函数 · 约 15 分钟

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

main.cpp
1#include <iostream>2 3int main() {4    int n = 3;5    while (n > 0) {6        std::cout << n << '\n';7        n--;8    }9    std::cout << "出发!\n";10    return 0;11}
输出
3
2
1
出发!

while 循环

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

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

  1. 开始前,给变量一个起始值(上面的 int n = 3;)。
  2. 每一圈先检查条件(n > 0)。
  3. 循环体里让变量变一变(n--),总有一天条件会不成立。

不知道要转几圈时,while 最合适。比如存钱:每个月存 800,存到 5000 要几个月?

main.cpp
1#include <iostream>2 3int main() {4    int saved = 0;5    int months = 0;6    while (saved < 5000) {7        saved += 800;8        months++;9    }10    std::cout << months << " 个月,存了 " << saved << '\n';11    return 0;12}
输出
7 个月,存了 5600

for 循环

「从 1 数到 5」这种事太常见了,C++ 有专门的写法,把三样东西放在一行里:

main.cpp
1#include <iostream>2 3int main() {4    for (int i = 1; i <= 5; i++) {5        std::cout << "第 " << i << " 次\n";6    }7    return 0;8}
输出
第 1 次
第 2 次
第 3 次
第 4 次
第 5 次

for (开始; 条件; 变化):先跑一次 int i = 1;然后每一圈先看 i <= 5,成立就跑循环体,跑完做 i++,再回去看条件。

在括号里声明的 i 只在这个循环里有用,循环结束它就没了。几个循环可以各用各的 i。

先猜一猜

这段程序显示几?

1#include <iostream>2 3int main() {4    int count = 0;5    for (int i = 0; i < 10; i += 3) {6        count++;7    }8    std::cout << count << '\n';9    return 0;10}

累加和计数

循环最常做的两件事:把一串数加起来,或者数有几个满足条件。做法一样:先准备一个从 0 开始的变量,每一圈往里加。

main.cpp
1#include <iostream>2 3int main() {4    int total = 0;5    int even = 0;6    for (int i = 1; i <= 10; i++) {7        total += i;8        if (i % 2 == 0) {9            even++;10        }11    }12    std::cout << "1 到 10 的和:" << total << '\n';13    std::cout << "其中偶数:" << even << " 个\n";14    return 0;15}
输出
1 到 10 的和:55
其中偶数:5 个

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

注意: total 要在循环外面声明。放在循环体里,每一圈都会重新从 0 开始,最后什么也没加上。

do while

do while 先跑循环体,再检查条件。所以它的循环体至少跑一次:

main.cpp
1#include <iostream>2 3int main() {4    int n = 10;5    while (n < 5) {6        std::cout << "while:" << n << '\n';7        n++;8    }9    do {10        std::cout << "do while:" << n << '\n';11        n++;12    } while (n < 5);13    return 0;14}
输出
do while:10

两个循环的条件一样,n < 5 都不成立。while 的循环体一次也没跑;do while 跑了一次,然后才发现该停了。注意 do while 最后的 while (...) 后面有分号。

break 和 continue

break 马上跳出整个循环;continue 跳过这一圈剩下的部分,直接进入下一圈。

main.cpp
1#include <iostream>2 3int main() {4    for (int i = 1; i <= 10; i++) {5        if (i % 3 == 0) {6            continue;7        }8        if (i > 7) {9            break;10        }11        std::cout << i << " ";12    }13    std::cout << '\n';14    return 0;15}
输出
1 2 4 5 7 

3 和 6 被 continue 跳过了;到了 8,break 让循环直接结束,9 和 10 根本没轮到。

找东西时 break 最好用:找到了就不用再找。比如找出第一个能被 7 整除的两位数:

main.cpp
1#include <iostream>2 3int main() {4    int found = 0;5    for (int n = 10; n < 100; n++) {6        if (n % 7 == 0) {7            found = n;8            break;9        }10    }11    std::cout << found << '\n';12    return 0;13}
输出
14

嵌套循环

循环体里可以再放一个循环。外面的循环每转一圈,里面的循环就从头到尾转一整遍。乘法表就是这样做的:

main.cpp
1#include <iostream>2 3int main() {4    for (int row = 1; row <= 4; row++) {5        for (int col = 1; col <= row; col++) {6            std::cout << col << "x" << row << "=" << col * row << "\t";7        }8        std::cout << '\n';9    }10    return 0;11}
输出
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	

外面的 row 决定是第几行;里面的 col 从 1 走到 row,所以第 1 行有 1 个,第 4 行有 4 个。每一行的最后,'\n' 换行(它在里面的循环外面)。点单步,看 row 和 col 是怎么一起变的。

死循环

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

1int n = 3;2while (n > 0) {3    std::cout << n << '\n';4}

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

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

有时候会故意写 while (true),在循环体里用 break 出来。这没问题,只要确定 break 一定会跑到。

练一练

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

练习 1

1 乘到 6

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

要显示
720
exercise1.cpp
1#include <iostream>2 3int main() {4    int product = 1;5 6    std::cout << product << '\n';7    return 0;8}
输出
点「运行」或按 Ctrl+Enter
练习 2

存够了吗

存款 balance 从 1000 开始,每年多 10%(balance = balance * 1.1;)。在第一个空行处用 while 算出要几年才能到 2000 以上;第二个空行处再算一次,这回每年多 20%(* 1.2)。

要显示
10%:8 年
20%:4 年
exercise2.cpp
1#include <iostream>2 3int main() {4    double balance = 1000;5    int years = 0;6 7    std::cout << "10%:" << years << " 年\n";8    balance = 1000;9    years = 0;10 11    std::cout << "20%:" << years << " 年\n";12    return 0;13}
输出
点「运行」或按 Ctrl+Enter
练习 3

星号三角形

用嵌套循环显示下面这个三角形:第 1 行 1 个 *,第 2 行 2 个,一直到第 4 行。

要显示
*
**
***
****
exercise3.cpp
1#include <iostream>2 3int main() {4 5    return 0;6}
输出
点「运行」或按 Ctrl+Enter

这一课学会了

  • while (条件) 先检查再跑,条件成立就一直转;适合不知道要转几圈的时候。
  • for (开始; 条件; 变化) 把三样东西写在一行,适合「从几数到几」;括号里声明的变量只在循环里有用。
  • 累加和计数:在循环外准备一个从 0 开始的变量,每一圈往里加。
  • do while 先跑再检查,循环体至少跑一次;最后有分号。
  • break 跳出整个循环,continue 跳到下一圈;嵌套循环里,外面转一圈,里面转一整遍。
  • 条件永远成立就是死循环;检查条件,检查变量有没有往对的方向变。