通过交互式演示理解 for、while、do-while 和范围 for 循环的工作原理
循环是编程中的基本控制结构,主要用于:
最常用的循环结构之一,特别适合已知或可计算迭代次数的场景。
// 语法结构
for (初始化; 条件判断; 更新表达式) {
// 循环体:需要重复执行的代码
}
执行顺序:① 初始化 → ② 条件判断 (真) → ③ 循环体 → ④ 更新表达式 → ② 条件判断 ... 直到条件为假。
基于条件的“前测试”循环:先判断条件,条件为真才执行循环体。
// 语法结构
while (条件判断) {
// 循环体:需要重复执行的代码
// (通常需要在循环体内部更新条件相关的变量)
}
如果初始条件即为假,循环体一次也不会执行。
基于条件的“后测试”循环:先执行循环体,再判断条件,条件为真则继续循环。
// 语法结构
do {
// 循环体:需要重复执行的代码
// (同样需要更新条件相关变量)
} while (条件判断); // 注意末尾的分号
无论初始条件如何,循环体至少会执行一次。
C++11 引入的简化语法,专为遍历容器(如 vector, array, string, map 等)或序列设计。
// 语法结构
for (元素类型 变量名 : 容器或序列) {
// 循环体:处理当前变量 '变量名'
}
自动处理迭代器和边界检查,代码更简洁、安全。
等待执行...
变量 | 值 |
---|---|
状态 | 未开始 |
// for 循环 (以计数为例)
设定 计数器 = 初始值
当 (计数器 < 结束条件值) 时,重复以下步骤:
执行 循环体内的操作
更新 计数器 (例如:计数器 = 计数器 + 步长)
循环结束
#include <iostream>
#include <vector>
#include <string> // 包含 string 头文件
using namespace std;//使用标准命名空间
int main() {
// --- 传统 for 循环 ---
cout << "传统 for 循环 (输出 0 到 4):" << endl;
for (int i = 0; i < 5; ++i) { // 初始化i=0; 条件i<5; 每次循环后i增加1
cout << i << " "; // 输出当前 i 的值
}
cout << endl << endl; // 换行分隔
// --- while 循环 ---
cout << "while 循环 (输出 0 到 4):" << endl;
int j = 0; // 初始化计数器
while (j < 5) { // 条件判断
cout << j << " "; // 输出当前 j 的值
++j; // 在循环体内更新计数器
}
cout << endl << endl;
// --- do-while 循环 ---
cout << "do-while 循环 (输出 0 到 4):" << endl;
int k = 0; // 初始化计数器
do {
cout << k << " "; // 先执行循环体
++k; // 更新计数器
} while (k < 5); // 后判断条件
cout << endl << endl;
// --- 范围 for 循环 (C++11) ---
cout << "范围 for 循环 (遍历 vector):" << endl;
vector numbers = {10, 20, 30, 40, 50}; // 定义一个整数向量
// 依次取出 numbers 中的每个元素,赋值给 num
for (int num : numbers) {
cout << num << " "; // 输出当前元素 num
}
cout << endl << endl;
cout << "范围 for 循环 (遍历 string):" << endl;
string message = "Hello"; // 定义一个字符串
// 依次取出 message 中的每个字符,赋值给 c
for (char c : message) {
cout << c << "-"; // 输出当前字符 c
}
cout << endl;
return 0; // 程序正常结束
}
循环条件永远为真,或忘记更新控制循环的变量,导致程序卡死。
// 错误示例:忘记更新计数器 i
int i = 0;
while (i < 10) {
cout << "这会一直打印!";
// 缺少 i++; 或类似更新语句
}
// 错误示例:条件始终为真
int x = 5;
while (x == 5) { // x 的值在循环中未改变
cout << "无限循环...";
}
避免方法:确保循环条件最终会变为假,并且控制变量在循环体内得到正确更新。
循环边界条件设置错误,导致多执行一次或少执行一次循环。
// 错误示例:想输出 0 到 9,但写成了 <= 9
// 或想访问数组索引 0 到 9,但条件写成了 i <= 10
int arr[10];
for (int i = 0; i <= 10; ++i) { // 错误:i=10 时越界
// arr[i] = i; // 当 i=10 时访问 arr[10],数组越界
}
避免方法:仔细检查循环的起始值、结束条件(`<` vs `<=`)以及数组/容器的有效索引范围(通常是 0 到 size-1)。
在遍历容器时,如果添加或删除元素,可能导致范围 for 内部使用的迭代器失效,引发未定义行为。
vector v = {1, 2, 3};
// 错误示例:遍历时添加元素 (非常危险!)
for (int x : v) {
if (x == 2) {
// v.push_back(4); // 这可能导致迭代器失效,行为不可预测
}
}
避免方法:如果需要在遍历时修改容器,通常应使用传统的基于迭代器或索引的 for 循环,并小心处理迭代器的有效性。
一个循环体内包含另一个完整的循环结构,常用于处理二维数据(如矩阵)或生成组合。
// 示例:打印 3x3 乘法表
for (int i = 1; i <= 3; ++i) { // 外层循环控制行
for (int j = 1; j <= 3; ++j) { // 内层循环控制列
cout << i << "*" << j << "=" << (i * j) << "\t";
}
cout << endl; // 每行结束后换行
}
break;
:立即跳出当前所在的整个循环结构。
continue;
:跳过当前循环体的剩余部分,直接开始下一次迭代(对 for 循环会先执行更新表达式)。
for (int i = 0; i < 10; ++i) {
if (i == 5) {
break; // 当 i 等于 5 时,退出 for 循环
}
if (i % 2 != 0) {
continue; // 如果 i 是奇数,跳过下面的 cout,进行下一次迭代
}
cout << i << " "; // 只会输出 0, 2, 4
}
// 循环结束后 i 的值是 5
标准库提供了许多基于循环思想的高级算法,如 `std::for_each`、`std::find_if`、`std::count_if` 等,通常更推荐使用这些算法,代码更简洁、意图更明确。
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
vector data = {1, 2, 3, 4, 5};
// 使用 std::for_each 打印每个元素的平方
for_each(data.begin(), data.end(), [](int n) {
cout << n * n << " "; // 输出: 1 4 9 16 25
});
cout << endl;