循环
在本课中,我们将使程序多次执行某段代码,也就是说,我们将使用循环。
动机
循环在编程中至关重要,因为它们允许我们重复执行一组指令多次。它们在各种场景中都很有用,包括:
- 🖥 数组操作:通常,我们需要对数组的每个元素单独执行操作。使用循环,我们可以轻松地显示或操作数组中的每个元素。
- ➗ 数学计算:在执行重复计算(例如计算阶乘或生成斐波那契数列)时,循环非常方便。它们使我们能够多次执行必要的运算,从而简化复杂的数学任务。
- 👾 游戏开发:想象一下在游戏中添加 10 个新对手到一个关卡中。使用循环,我们可以轻松地重复创建对手的代码,而无需编写 10 次。
总而言之,循环为我们提供了一种自动化重复任务和高效处理大量数据的方法。它们通过减少代码重复显著提高了我们程序的灵活性和强大功能。
在上一课关于向量的课程中,我们已经演示了一个显示数组所有元素的循环:
for (int n : numbers)
{
std::cout << n << ' ';
}
这是 C++ 中最简单的循环版本,但本课中我们将介绍其他类型的循环。
解释
在 C++ 中,有三种类型的循环:
for
- 基于范围的版本
- 基本版本
while
do ... while
最常用的是 for
和 while
,我们将在本课中介绍它们。如果您想了解 do ... while
循环,请参阅文章:do ... while
循环。
迭代 - 单次循环体执行。
基于范围的 for
这种类型的循环最常用于处理数组,尽管它也可以以其他方式使用。

在动机部分提供的示例中,我们有一种特殊类型的循环,称为基于范围的 for 循环。它是用于处理项目集合的常规 for
循环的变体。值得一提的是,C++ 中的数组也是一个范围,因此我们可以使用此循环对其进行迭代。
看这个例子
std::vector<int> numbers = { 13, 42, -1, 0, -3, -5 };
for (int n : numbers)
{
std::cout << n << ' ';
}
此循环依次遍历数组 numbers
的每个元素并将其写入变量 n
。然后执行花括号中包含的代码块。在这种情况下,它只是简单地打印数字。
请注意,变量名 n
后面是冒号 (:
),而不是分号 (;
)!在这种表示法中我们不使用任何等号 (=
),因为每个元素的值将依次自动赋值给 n
。
更改内容
可以在循环体中修改数组的每个元素。让我们编写一个程序,将数组中每个偶数增加 100,并减少每个奇数 100。使用元素的引用。在我们精确解释它是什么以及如何工作之前,让我们看看下面的例子:
- ✅ 修改原始数字
- ❌ 修改副本
std::vector<int> numbers = { 13, 42, -1, 0, -3, -5 };
for (int& n : numbers)
{
if (n % 2 == 0) {
n += 100;
}
else {
n -= 100;
}
}
// numbers: { -87, 142, -101, 100, -103, -105 }
std::vector<int> numbers = { 13, 42, -1, 0, -3, -5 };
for (int n : numbers)
{
if (n % 2 == 0) {
n += 100;
}
else {
n -= 100;
}
}
// numbers: { 13, 42, -1, 0, -3, -5 }
在第一种情况下,我们使用了引用类型,它在类型名后面用与号 (&
) 表示。目前需要知道的关键是:
- 使用引用类型(例如
for (int& n : numbers)
)
在这种情况下,变量n
使用引用类型,允许您修改数组的原始元素。这是因为在每次循环迭代中,变量n
都会成为当前处理元素的别名。 - 不使用引用(例如
for (int n : numbers)
)
另一方面,如果我们不使用引用类型,则在每次循环迭代中,当前处理元素的副本会创建并赋值给变量n
。这意味着数组的原始元素不能被修改。
这适用于任何类型,不仅仅是 int
。这意味着同样可以修改字符串数组、实数(例如 float
)和我们将在后续课程中介绍的自定义类型的元素。
我们将在接下来的课程中详细讨论引用:引用。
带有初始化列表
这个循环也可以与所谓的初始化列表一起使用。
- 数字
- 字符串
for (int number : { 2, 1, 3, 7 })
{
std::cout << number << ' ';
}
for (std::string str : { "hello", "world", "using", "initializer", "list" })
{
std::cout << str << ' ';
}
请注意,您不能使用基于范围的 for
循环来修改初始化列表的元素,因此以下代码将产生错误:
for (int& a_number_from_list : { 2, 1, 3, 7 })
更多内容
基于范围的 for 循环简单易用,但同时又非常灵活。我们只触及了它能做到的冰山一角。我们将在课程后面更详细地介绍它们。
while
循环

我们现在有意转向 while
循环,而不是基本的 for
循环,因为这将使解释更容易。while 循环只要条件满足就执行其主体。
int number = 0;
while (number <= 3)
{
std::cout << number << ' ';
number++;
}
0 1 2 3
条件将在每次循环执行之前检查,只要它满足,即在本例中只要 number
小于或等于 3
,循环体就会执行。
- 打印
number
- 将
number
增加 1
在最后一次循环执行后,number
的值将等于 4
,因此条件将不满足,导致循环终止,计算机继续执行下一条指令。
for
循环

这个循环是对某种非常频繁重复模式的简化,它通常用于遍历某个范围(例如数字范围)。
让我们从一个例子开始
for (int i = 0; i < 10; i++)
{
std::cout << i << ' ';
}
上面的循环显示从 0 到 9 的数字。for
的圆括号包含三部分,由分号分隔。
片段 | 描述 |
---|---|
int i = 0 | 初始指令(通常是变量的创建) |
i < 10 | 条件 |
i++ | 迭代表达式 |
当程序开始执行 for
循环时,它会执行初始语句一次——在我们的例子中,它会创建一个变量并给它赋值 0
。然后程序会
- 检查条件
- 不满足:跳出循环
- 满足:转到第 2 点
- 执行循环体
- 执行迭代表达式并转到第 1 点。
上面的 for
循环等价于
int i = 0;
while (i < 10)
{
std::cout << i << ' ';
i++;
}
遍历数组
for
循环经常用于遍历数组,在我们需要访问迭代次数或不想遍历整个范围的情况下。
std::vector<int> numbers = {10, 13, 15, 18, 60};
for (int i = 0; i < numbers.size(); i++)
{
std::cout << "numbers[" << i << "]: " << numbers[i] << '}
}
std::vector<int> numbers = {10, 13, 15, 18, 60};
for (int i = 0; i < numbers.size() / 2; i++)
{
std::cout << "numbers[" << i << "]: " << numbers[i] << '}
}
空括号
for
循环括号中给出的代码是可选的。分号是必需的。
for ( ; ; )
{
// code
}
上面的代码将使 for
循环无限执行(因为条件为空),除非我们手动中断它...
中断循环 (break
)
我们可以使用 break
语句在任何时候停止循环。
for (int i = 0; i < 10; i++)
{
if (i == 5)
break;
std::cout << i << ' ';
}
这个循环将显示从 0 到 4 的数字,因为当 i
等于 5
时,循环的执行将被中止。我们可以用同样的方式中断 while
循环。
跳过单个迭代 (continue
)
要跳过当前循环迭代的进一步执行,我们使用 continue
语句。
for (int i = 0; i < 10; i++)
{
if (i == 5)
continue;
std::cout << i << ' ';
}
该循环将显示从 0
到 9
的数字,不包括数字 5
,因为在执行显示指令 (std::cout
) 之前,程序将跳转到下一个迭代。
请注意,在 for
循环中使用 continue
不会省略迭代表达式(参见上图)。
示例
本节需要改进。您可以通过编辑此文档页面来帮助我们。
潜在错误
本节需要改进。您可以通过编辑此文档页面来帮助我们。
附加信息
本节需要改进。您可以通过编辑此文档页面来帮助我们。