循环
要把同样的事做很多遍,不用把代码抄很多遍,写一个循环就行。循环是单步最好看的地方:点单步,看着程序一圈一圈地转,变量一次一次地变。
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 先看括号里的条件:成立,就跑一遍循环体,然后回到开头再看条件;不成立,就跳过循环体,接着往下跑。
一个能停下来的循环,通常有三样东西:
- 开始前,给变量一个起始值(上面的
int n = 3;)。 - 每一圈先检查条件(
n > 0)。 - 循环体里让变量变一变(
n--),总有一天条件会不成立。
不知道要转几圈时,while 最合适。比如存钱:每个月存 800,存到 5000 要几个月?
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++ 有专门的写法,把三样东西放在一行里:
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}
i 依次是 0、3、6、9,四个都小于 10,循环体跑了 4 次。下一次 i 变成 12,条件不成立,循环结束。
累加和计数
循环最常做的两件事:把一串数加起来,或者数有几个满足条件。做法一样:先准备一个从 0 开始的变量,每一圈往里加。
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 先跑循环体,再检查条件。所以它的循环体至少跑一次:
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 跳过这一圈剩下的部分,直接进入下一圈。
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 整除的两位数:
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
嵌套循环
循环体里可以再放一个循环。外面的循环每转一圈,里面的循环就从头到尾转一整遍。乘法表就是这样做的:
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 乘到 6
✓用一个循环算出 1 × 2 × 3 × 4 × 5 × 6,显示结果 720。
720
1#include <iostream>2 3int main() {4 int product = 1;5 6 std::cout << product << '\n';7 return 0;8}
存够了吗
✓存款 balance 从 1000 开始,每年多 10%(balance = balance * 1.1;)。在第一个空行处用 while 算出要几年才能到 2000 以上;第二个空行处再算一次,这回每年多 20%(* 1.2)。
10%:8 年 20%:4 年
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}
星号三角形
✓用嵌套循环显示下面这个三角形:第 1 行 1 个 *,第 2 行 2 个,一直到第 4 行。
* ** *** ****
1#include <iostream>2 3int main() {4 5 return 0;6}
这一课学会了
while (条件)先检查再跑,条件成立就一直转;适合不知道要转几圈的时候。for (开始; 条件; 变化)把三样东西写在一行,适合「从几数到几」;括号里声明的变量只在循环里有用。- 累加和计数:在循环外准备一个从 0 开始的变量,每一圈往里加。
do while先跑再检查,循环体至少跑一次;最后有分号。break跳出整个循环,continue跳到下一圈;嵌套循环里,外面转一圈,里面转一整遍。- 条件永远成立就是死循环;检查条件,检查变量有没有往对的方向变。