循环结构是程序设计中实现代码重复执行的基础,C++ 提供了多种循环语句,用于以灵活应对不同的重复场景。本文将详细解析 for、while、do-while 三种循环的语法、特性、适用场景及实战技巧,帮助你高效控制程序流程。
一、循环的本质与应用场景
循环的核心作用是让一段代码按照指定条件重复执行,避免重复编写相同逻辑。常见应用场景包括:
- 遍历数组、容器等数据结构(如输出数组所有元素)。
- 执行固定次数的操作(如计算 1 到 100 的和)。
- 满足特定条件前持续运行(如等待用户输入正确值)。
C++ 提供三种循环语句,核心区别在于循环条件的初始化方式 和循环变量的更新时机:
for循环:适合已知循环次数的场景(初始化、条件、更新在同一行)。while循环:适合循环次数未知,仅依赖条件判断的场景。do-while循环:适合至少执行一次的场景(先执行后判断)。
二、for 循环:结构化的固定次数循环
for 循环是最常用的循环结构,语法清晰,将循环控制的三个核心部分(初始化、条件判断、更新)集中定义,适合循环次数已知的场景。
2.1 基本语法
cpp
运行
for (初始化表达式; 循环条件; 更新表达式) {
// 循环体(重复执行的代码)
}
- 初始化表达式:循环开始前执行一次(通常用于定义循环变量)。
- 循环条件 :每次循环前判断,结果为
true则执行循环体,false则退出。 - 更新表达式:每次循环体执行后执行(通常用于更新循环变量)。
执行流程:初始化 → 判断条件 → 条件为真执行循环体 → 更新变量 → 重复判断条件... → 条件为假退出。
2.2 基础示例
cpp
运行
#include <iostream>
using namespace std;
int main() {
// 示例1:计算 1 到 10 的和
int sum = 0;
for (int i = 1; i <= 10; ++i) { // i从1开始,每次+1,直到i>10
sum += i;
}
cout << "1到10的和:" << sum << endl; // 输出55
// 示例2:遍历数组
int arr[] = {10, 20, 30, 40};
int n = sizeof(arr) / sizeof(arr[0]); // 数组长度
for (int i = 0; i < n; ++i) { // 从0遍历到n-1
cout << arr[i] << " ";
}
// 输出:10 20 30 40
return 0;
}
2.3 灵活用法
(1)省略部分表达式
for 循环的三个表达式均可省略,但分号 ; 必须保留:
cpp
运行
// 省略初始化(循环变量在外部定义)
int i = 0;
for (; i < 5; ++i) {
cout << i << " "; // 输出0 1 2 3 4
}
// 省略更新(在循环体内更新变量)
for (int j = 0; j < 5; ) {
cout << j << " ";
j++; // 循环体内更新
}
// 无限循环(省略所有表达式,需在循环体内用break退出)
for (;;) {
cout << "无限循环中...";
break; // 必须手动退出,否则死循环
}
(2)多循环变量
支持同时初始化和更新多个变量(用逗号分隔):
cpp
运行
// 同时控制两个变量,打印1-5和5-1
for (int i = 1, j = 5; i <= 5; ++i, --j) {
cout << i << "和" << j << " ";
}
// 输出:1和5 2和4 3和3 4和2 5和1
(3)范围 for 循环(C++11)
遍历容器或数组时,可使用更简洁的范围 for 循环(无需手动控制下标):
cpp
运行
int arr[] = {1, 2, 3, 4};
// 范围for循环:自动遍历数组所有元素,num是当前元素的副本
for (int num : arr) {
cout << num << " "; // 输出1 2 3 4
}
// 若需修改元素,用引用(&)
for (int& num : arr) {
num *= 2; // 所有元素乘2
}
// 此时arr变为{2,4,6,8}
注意 :范围 for 循环适用于无需修改循环顺序的场景,无法直接获取元素下标。
三、while 循环:基于条件的灵活循环
while 循环通过判断条件决定是否执行循环体,适合循环次数未知(仅依赖条件)的场景,语法更简洁。
3.1 基本语法
cpp
运行
while (循环条件) {
// 循环体
}
执行流程:判断条件 → 条件为真执行循环体 → 重复判断条件... → 条件为假退出。
特点:循环变量的初始化在循环外,更新在循环体内,适合条件复杂的场景。
3.2 基础示例
cpp
运行
#include <iostream>
using namespace std;
int main() {
// 示例1:计算用户输入的整数之和,直到输入0停止
int sum = 0;
int num;
cout << "请输入整数(输入0结束):";
cin >> num;
while (num != 0) { // 条件:输入的数不等于0
sum += num;
cout << "请输入整数(输入0结束):";
cin >> num; // 更新循环变量
}
cout << "总和:" << sum << endl;
// 示例2:遍历数组(类似for循环)
int arr[] = {10, 20, 30};
int i = 0;
while (i < 3) {
cout << arr[i] << " ";
i++; // 手动更新循环变量
}
// 输出:10 20 30
return 0;
}
3.3 常见用法:无限循环与退出控制
while(true) 可创建无限循环,需在循环体内用 break 手动退出:
cpp
运行
// 无限循环:直到用户输入正确的密码
string password;
while (true) { // 条件恒为真
cout << "请输入密码:";
cin >> password;
if (password == "123456") {
cout << "密码正确!" << endl;
break; // 满足条件退出循环
} else {
cout << "密码错误,请重试!" << endl;
}
}
四、do-while 循环:至少执行一次的循环
do-while 循环与 while 循环类似,但先执行一次循环体,再判断条件,适合需要 "至少执行一次" 的场景(如用户输入验证)。
4.1 基本语法
cpp
运行
do {
// 循环体(至少执行一次)
} while (循环条件); // 注意末尾有分号
执行流程:执行循环体 → 判断条件 → 条件为真则再次执行循环体... → 条件为假退出。
4.2 基础示例
cpp
运行
#include <iostream>
using namespace std;
int main() {
// 示例:验证用户输入(至少提示一次)
int age;
do {
cout << "请输入你的年龄(1-120):";
cin >> age;
} while (age < 1 || age > 120); // 年龄不合法则重复输入
cout << "你的年龄是:" << age << endl;
return 0;
}
对比 while 和 do-while:
- 若初始条件不满足,
while循环一次都不执行,do-while至少执行一次。 - 例如初始
age=200时,do-while会先提示输入,再判断;while则直接跳过。
五、循环控制:break 与 continue
在循环中,可通过 break 和 continue 控制流程:
5.1 break:立即退出循环
break 用于终止当前循环,跳出循环体执行后续代码:
cpp
运行
// 查找数组中第一个偶数并输出
int arr[] = {1, 3, 4, 5, 6};
for (int num : arr) {
if (num % 2 == 0) { // 找到偶数
cout << "第一个偶数:" << num << endl; // 输出4
break; // 退出循环,不再检查后续元素
}
}
5.2 continue:跳过本次循环
continue 用于跳过当前循环的剩余部分,直接进入下一次循环:
cpp
运行
// 输出1-10中的奇数
for (int i = 1; i <= 10; ++i) {
if (i % 2 == 0) { // 若为偶数
continue; // 跳过后续代码,直接进入下一次循环
}
cout << i << " "; // 仅输出奇数:1 3 5 7 9
}
5.3 注意事项
break仅退出当前所在的循环(嵌套循环中不影响外层循环)。continue不终止循环,仅跳过当前迭代,需确保循环变量能正常更新(否则可能死循环)。
六、嵌套循环:循环中的循环
嵌套循环是指在一个循环体内包含另一个循环,常用于处理二维数据(如矩阵)或需要多层重复的场景。
6.1 基础示例:打印九九乘法表
cpp
运行
#include <iostream>
using namespace std;
int main() {
// 外层循环控制行数(1-9)
for (int i = 1; i <= 9; ++i) {
// 内层循环控制每行的列数(1-i)
for (int j = 1; j <= i; ++j) {
cout << j << "*" << i << "=" << j*i << "\t";
}
cout << endl; // 每行结束换行
}
return 0;
}
执行逻辑:外层循环执行 1 次,内层循环执行 i 次(i 为外层循环变量),总执行次数为 1+2+...+9=45 次。
6.2 嵌套循环中的 break 与 continue
break仅退出当前内层循环,外层循环继续执行。continue仅跳过当前内层循环的本次迭代。
cpp
运行
// 外层循环
for (int i = 1; i <= 3; ++i) {
cout << "外层循环 i=" << i << endl;
// 内层循环
for (int j = 1; j <= 3; ++j) {
if (j == 2) {
// break; // 若用break,内层循环在j=2时退出,输出j=1后结束
continue; // 若用continue,跳过j=2,继续j=3
}
cout << " 内层循环 j=" << j << endl;
}
}
七、三种循环的对比与选择
| 循环类型 | 语法特点 | 适用场景 | 执行次数确定性 |
|---|---|---|---|
for |
初始化、条件、更新集中定义 | 已知循环次数(如遍历数组、固定次数操作) | 确定或可预测 |
while |
仅条件判断,初始化和更新在外部 | 未知循环次数(仅依赖条件,如等待事件) | 不确定 |
do-while |
先执行后判断,至少执行一次 | 至少执行一次的场景(如用户输入验证) | 至少 1 次 |
选择建议:
- 遍历数组、容器或固定次数循环 → 优先用
for(结构清晰)。 - 条件复杂且循环次数未知 → 用
while。 - 必须执行一次循环体(如输入验证) → 用
do-while。
八、常见错误与最佳实践
8.1 常见错误
-
死循环 循环条件始终为真且无
break退出,导致程序无限执行:cpp
运行
// 错误:i始终为1,条件i <= 5恒成立 for (int i = 1; i <= 5; ) { // 忘记更新i cout << i << " "; } -
循环变量更新错误循环变量未正确更新,导致循环次数异常:
cpp
运行
// 错误:i++写成i--,导致i越来越小,条件i < 5恒成立 for (int i = 0; i < 5; i--) { cout << i << " "; // 死循环(i为0,-1,-2...) } -
范围 for 循环修改元素未用引用试图修改元素但未使用引用,导致修改无效:
cpp
运行
int arr[] = {1,2,3}; for (int num : arr) { // num是副本,不是原元素 num *= 2; // 原数组不变 }
8.2 最佳实践
-
循环变量命名清晰 避免使用
i,j,k以外的模糊命名,如遍历数组时用index,遍历容器时用elem。 -
控制循环体复杂度循环体代码过长时,可拆分为函数,提高可读性:
cpp
运行
// 推荐:将复杂逻辑封装为函数 void processElement(int num) { // 复杂处理逻辑 } for (int num : arr) { processElement(num); // 循环体简洁 } -
避免嵌套过深嵌套循环超过 3 层时,代码可读性差,可考虑扁平化处理(如合并循环条件)。
-
优先使用标准算法替代手动循环 遍历容器时,优先使用
<algorithm>库中的算法(如std::for_each):cpp
运行
#include <algorithm> vector<int> vec = {1,2,3}; // 用for_each遍历,配合lambda表达式 for_each(vec.begin(), vec.end(), [](int num) { cout << num << " "; });
九、总结
循环结构是 C++ 控制程序流程的核心机制,for、while、do-while 分别适用于不同场景:
for循环结构化强,适合已知次数的循环。while循环灵活,适合条件驱动的未知次数循环。do-while循环确保至少执行一次,适合输入验证等场景。
掌握循环控制语句(break、continue)和嵌套循环的使用,能高效处理重复逻辑。实际开发中,应根据具体场景选择合适的循环类型,并注意避免死循环、变量更新错误等问题,编写清晰、高效的循环代码。