C++ 中的循环语句用于重复执行一段代码,直到满足特定条件。循环是编程中最基本的控制结构之一。
for 循环
传统 for 循环
// 基本语法:for (初始化; 条件; 更新)
for (int i = 0; i < 10; i++) {
std::cout << i << " ";
}
// 输出:0 1 2 3 4 5 6 7 8 9
// 多变量初始化和更新
for (int i = 0, j = 10; i < j; i++, j--) {
std::cout << "i=" << i << ", j=" << j << std::endl;
}
// 省略部分组件
int i = 0;
for (; i < 10; ) { // 省略初始化和更新
std::cout << i++ << " ";
}
// 无限循环
for (;;) {
// 需要内部 break 来退出
if (condition) break;
}
范围 for 循环(C++11)
// 遍历数组
int arr[] = {1, 2, 3, 4, 5};
for (int x : arr) {
std::cout << x << " ";
}
// 遍历容器
std::vector<int> vec = {10, 20, 30, 40, 50};
for (int x : vec) {
std::cout << x << " ";
}
// 使用引用避免拷贝
std::vector<std::string> strings = {"hello", "world"};
for (const std::string& s : strings) { // const 引用
std::cout << s << " ";
}
// 修改元素
for (int& x : vec) { // 非 const 引用
x *= 2;
}
// 使用 auto 自动推导类型
std::map<std::string, int> scores = {{"Alice", 90}, {"Bob", 85}};
for (const auto& [name, score] : scores) { // C++17 结构化绑定
std::cout << name << ": " << score << std::endl;
}
基于索引的迭代技巧
// 反向遍历
for (int i = 9; i >= 0; i--) {
std::cout << i << " ";
}
// 步长不为 1
for (int i = 0; i < 100; i += 10) {
std::cout << i << " "; // 0 10 20 ... 90
}
// 遍历二维数组
int matrix[3][4];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
matrix[i][j] = i * 4 + j;
}
}
// 使用 size_t 避免符号问题
std::vector<int> vec = {1, 2, 3};
for (size_t i = 0; i < vec.size(); i++) {
std::cout << vec[i] << " ";
}
while 循环
基本 while 循环
int i = 0;
while (i < 10) {
std::cout << i << " ";
i++;
}
// 条件依赖外部输入
int num;
while (std::cin >> num && num != 0) {
std::cout << "You entered: " << num << std::endl;
}
// 使用 while 处理链表
struct Node {
int data;
Node* next;
};
Node* current = head;
while (current != nullptr) {
std::cout << current->data << " ";
current = current->next;
}
while 循环的常见模式
// 查找模式
std::vector<int> vec = {1, 2, 3, 4, 5};
size_t index = 0;
while (index < vec.size() && vec[index] != target) {
index++;
}
// 读取文件
std::ifstream file("data.txt");
std::string line;
while (std::getline(file, line)) {
std::cout << line << std::endl;
}
// 事件循环
bool running = true;
while (running) {
Event event = getNextEvent();
if (event.type == EventType::QUIT) {
running = false;
}
processEvent(event);
}
do-while 循环
至少执行一次的循环:
// 基本语法
int i = 0;
do {
std::cout << i << " ";
i++;
} while (i < 10);
// 即使条件初始为假,也会执行一次
int x = 10;
do {
std::cout << "This will print once" << std::endl;
} while (x < 5);
// 菜单驱动程序
int choice;
do {
std::cout << "1. Option 1\n";
std::cout << "2. Option 2\n";
std::cout << "3. Exit\n";
std::cout << "Enter choice: ";
std::cin >> choice;
switch (choice) {
case 1: handleOption1(); break;
case 2: handleOption2(); break;
case 3: std::cout << "Exiting...\n"; break;
default: std::cout << "Invalid choice\n";
}
} while (choice != 3);
// 输入验证
int age;
do {
std::cout << "Enter age (0-150): ";
std::cin >> age;
} while (age < 0 || age > 150);
循环控制语句
break 语句
// 提前退出循环
for (int i = 0; i < 100; i++) {
if (i == 50) {
break; // 立即退出循环
}
std::cout << i << " ";
}
// 在嵌套循环中,break 只退出最内层循环
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == 1) {
break; // 只退出内层循环
}
std::cout << "(" << i << "," << j << ") ";
}
std::cout << std::endl;
}
// 使用标志变量退出多层循环
bool found = false;
for (int i = 0; i < rows && !found; i++) {
for (int j = 0; j < cols && !found; j++) {
if (matrix[i][j] == target) {
found = true;
}
}
}
continue 语句
// 跳过当前迭代的剩余部分
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // 跳过偶数
}
std::cout << i << " "; // 只打印奇数
}
// 在 while 循环中使用
int i = 0;
while (i < 10) {
i++;
if (i % 2 == 0) {
continue;
}
std::cout << i << " ";
}
// 过滤处理
std::vector<int> numbers = {1, -2, 3, -4, 5};
for (int num : numbers) {
if (num < 0) {
continue; // 跳过负数
}
process(num);
}
goto 语句(慎用)
// goto 可以跳出多层循环(但通常有更好的方法)
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (condition) {
goto exit_loops;
}
}
}
exit_loops:
std::cout << "Exited nested loops" << std::endl;
// 错误处理场景(C 风格,不推荐)
if (!initResource1()) goto cleanup;
if (!initResource2()) goto cleanup1;
if (!initResource3()) goto cleanup2;
// 使用资源
cleanup2:
releaseResource2();
cleanup1:
releaseResource1();
cleanup:
return;
现代 C++ 循环技巧
使用算法替代循环
#include <algorithm>
#include <numeric>
std::vector<int> vec = {1, 2, 3, 4, 5};
// 替代 for 循环累加
int sum = std::accumulate(vec.begin(), vec.end(), 0);
// 替代查找循环
auto it = std::find(vec.begin(), vec.end(), 3);
// 替代转换循环
std::transform(vec.begin(), vec.end(), vec.begin(),
[](int x) { return x * 2; });
// 替代过滤循环
std::copy_if(vec.begin(), vec.end(),
std::back_inserter(filtered),
[](int x) { return x > 2; });
// for_each 算法
std::for_each(vec.begin(), vec.end(),
[](int x) { std::cout << x << " "; });
并行循环(C++17)
#include <execution>
std::vector<int> vec(1000000);
// 并行执行
std::for_each(std::execution::par,
vec.begin(), vec.end(),
[](int& x) { x = expensive_computation(x); });
// 并行累加
int sum = std::reduce(std::execution::par,
vec.begin(), vec.end(), 0);
使用迭代器
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用迭代器遍历
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
// 反向迭代器
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
std::cout << *it << " ";
}
// 使用 std::advance
auto it = vec.begin();
std::advance(it, 3); // 移动到第 4 个元素
循环优化技巧
循环展开
// 手动循环展开
for (int i = 0; i < n; i += 4) {
process(arr[i]);
process(arr[i+1]);
process(arr[i+2]);
process(arr[i+3]);
}
// 处理剩余元素
for (int i = n - (n % 4); i < n; i++) {
process(arr[i]);
}
循环不变量外提
// 低效
for (int i = 0; i < n; i++) {
result += arr[i] * expensive_function();
}
// 高效
int factor = expensive_function();
for (int i = 0; i < n; i++) {
result += arr[i] * factor;
}
缓存友好的循环
// 列优先遍历(缓存不友好)
for (int j = 0; j < cols; j++) {
for (int i = 0; i < rows; i++) {
process(matrix[i][j]);
}
}
// 行优先遍历(缓存友好)
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
process(matrix[i][j]);
}
}
循环中的常见陷阱
无限循环
// 忘记更新循环变量
int i = 0;
while (i < 10) {
std::cout << i << " ";
// 忘记 i++
}
// 浮点数比较
for (double x = 0.0; x != 1.0; x += 0.1) {
// 可能永远不会精确等于 1.0
}
// 正确做法
for (double x = 0.0; x < 1.0; x += 0.1) {
// 使用 < 而不是 !=
}
越界访问
std::vector<int> vec = {1, 2, 3};
// 错误:<=
for (size_t i = 0; i <= vec.size(); i++) {
std::cout << vec[i]; // 越界!
}
// 正确:<
for (size_t i = 0; i < vec.size(); i++) {
std::cout << vec[i];
}
在循环中修改容器
// 危险:在遍历时修改
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
if (*it == 3) {
vec.erase(it); // 迭代器失效!
}
}
// 正确做法
vec.erase(std::remove(vec.begin(), vec.end(), 3), vec.end());
// 或使用 while 循环
auto it = vec.begin();
while (it != vec.end()) {
if (*it == 3) {
it = vec.erase(it);
} else {
++it;
}
}
循环的最佳实践
// 1. 优先使用范围 for 循环
for (const auto& item : container) {
process(item);
}
// 2. 使用有意义的循环变量名
for (int studentIndex = 0; studentIndex < studentCount; studentIndex++) {
// 比 i, j, k 更清晰
}
// 3. 将复杂的循环体提取为函数
for (const auto& item : items) {
processItem(item); // 清晰的抽象
}
// 4. 避免深层嵌套
// 使用早期 continue 减少嵌套
for (const auto& item : items) {
if (!item.isValid()) continue;
if (!item.isReady()) continue;
// 主要逻辑
process(item);
}
// 5. 考虑使用算法替代显式循环
auto result = std::any_of(vec.begin(), vec.end(),
[](int x) { return x > 100; });
循环是程序中最常用的控制结构之一。选择合适的循环类型、正确使用循环控制语句、避免常见陷阱,可以编写出高效、可读、可维护的代码。现代 C++ 提供的范围 for 循环、算法库和并行执行策略,让循环操作更加简洁和高效。