除了 while
循环,C++ 还有两种循环结构。我们依次介绍一下。
do while
循环
在 C++ 中,还有一种循环叫做 do while
循环,这种循环和 while
循环差不多,我们先来看结构。
do {
循环体
} while (条件);
这种循环的流程是:先开始执行循环体,然后再进行 while
循环的条件判断,我们看看流程图。
因此可以发现,无论条件如何,do while
循环总是会执行至少一次。
for
循环
我们先给出结构框架:
for (初始化; 条件; 更新语句) {
循环体
}
在这个框架中出现了几个新名词:初始化指定义循环的初始状态,也就是循环开始时是什么样的;更新语句是在每次循环后对状态进行更新,也就是执行完循环体后进行一些操作。
观察下面一段代码:
for (int i = 1; i <= n; ++i) cout << i << endl;
这段代码中:
int i = 1
是初始化,我们定义了一个变量 $i$,并赋了初值为 $1$。这个变量 $i$ 被称为循环变量,经常以 $i$、$j$、$k$ 等命名。在for
循环中定义的循环变量只有在这个循环内部(包括初始化、条件、更新语句和循环体)才可以使用。i <= n
是条件,这与我们在while
循环中学到的相同。++i
是更新语句,在每次循环结束以后会执行一次。
这段代码的意思是,让 $i$ 开始为 $1$。若 $i \le n$,则执行 cout << i << endl
,也就是输出 $i$,否则结束循环。每一次执行完循环体后,$i$ 变为 $i+1$。
这是 for
循环的流程图:
如果把上面的代码改成 while
循环,应该怎么写呢?
int i = 1;
while (i <= n) {
cout << i << endl;
++i;
}
此时我们可以发现,for
循环和 while
循环是可以相互转化的(当然 do while
循环也同理),并且在大多数时候 for
循环要比 while
循环轻量,简便。
值得注意的是,for
循环的初始化、条件、更新语句都不是必要的,甚至只写两个分号也可以构成 for
循环。
循环操作
我们通常可以对循环做两种操作:退出循环、跳过循环体的余下部分。
break
的作用是跳出一层循环,而 continue
的作用就是跳过本次循环中未执行的语句,直接进入下一轮循环。
使用这两个语句可以使循环(或循环体)提前结束,且只能控制这两种语句上一层循环的流程。break
与 continue
语句均可在三种循环语句的循环体中使用。
举个例子,观察下面的几段代码:
for (int i = 1; i <= 10; ++i) {
cout << i << ' ';
}
for (int i = 1; i <= 10; ++i) {
if (i == 6) break;
cout << i << ' ';
}
for (int i = 1; i <= 10; ++i) {
if (i == 6) continue;
cout << i << ' ';
}
这几段代码中:
- 第一份代码可以直接输出从 $1$ 到 $10$ 的所有数。
- 第二份代码中,我们使 $i$ 等于 $6$ 的时候退出循环,因此不会继续输出;
- 第三份代码中,我们使 $i$ 等于 $6$ 的时候跳过这次循环的剩余部分,然后进入下一次循环,因此只有 $6$ 不会被输出。
它们的运行结果是这样的:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5
1 2 3 4 5 7 8 9 10
这时我们可以想到,如果判断不满足条件时直接使用 break
跳出循环,是等价于写一个循环条件的,这也就是上文所说「循环条件可以省略」的原因。
循环的应用
我们来看几道深度应用循环的题目:
给定一个数 $x$,请判断他是否是质数。
我们知道,对于一个质数,它只有 $1$ 和它本身两个因数,所以我们枚举所有在 $[2,x-1]$ 的数 $d$,判断 $d|x$ (即 $x$ 能被 $d$ 整除)是否成立即可。
输出一个数所有的倍数。
我们只需要将 $i$ 初始设为 $x$,每次循环结束让 $i$ 变为 $i+x$ 即可。
输出一个数 $x$ 中数字 7 的个数。
我们先将数转化为数字,然后统计即可。于是考虑如何将数转化为数字。
在十进制下,每个数的最后一位是 $x\bmod 10$。于是我们就可以写出这样的代码:
while (x != 0) {
if (x % 10 == 7) ++ans;
x /= 10;
}
至此,我们已经学会了循环的全部内容。在今后的学习中,循环将是总会用到的知识点,希望各位能够熟练掌握。