C++ 循环语句可视化教学

通过交互式演示理解 for、while、do-while 和范围 for 循环的工作原理

循环结构概述

动态演示与交互练习

暗色模式

迭代输出

等待执行...

变量跟踪

变量
状态未开始

执行日志

日志记录区...

循环原理与代码示例

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; // 程序正常结束
}

常见错误与陷阱

1. 无限循环 (Infinite Loop)

循环条件永远为真,或忘记更新控制循环的变量,导致程序卡死。

// 错误示例:忘记更新计数器 i
int i = 0;
while (i < 10) {
    cout << "这会一直打印!";
    // 缺少 i++; 或类似更新语句
}

// 错误示例:条件始终为真
int x = 5;
while (x == 5) { // x 的值在循环中未改变
    cout << "无限循环...";
}

避免方法:确保循环条件最终会变为假,并且控制变量在循环体内得到正确更新。

2. 差一错误 (Off-by-One Error)

循环边界条件设置错误,导致多执行一次或少执行一次循环。

// 错误示例:想输出 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)。

3. 在范围 for 循环中修改容器(导致迭代器失效)

在遍历容器时,如果添加或删除元素,可能导致范围 for 内部使用的迭代器失效,引发未定义行为。

vector v = {1, 2, 3};
// 错误示例:遍历时添加元素 (非常危险!)
for (int x : v) {
    if (x == 2) {
        // v.push_back(4); // 这可能导致迭代器失效,行为不可预测
    }
}

避免方法:如果需要在遍历时修改容器,通常应使用传统的基于迭代器或索引的 for 循环,并小心处理迭代器的有效性。

扩展与进阶

1. 嵌套循环 (Nested Loops)

一个循环体内包含另一个完整的循环结构,常用于处理二维数据(如矩阵)或生成组合。

// 示例:打印 3x3 乘法表
for (int i = 1; i <= 3; ++i) { // 外层循环控制行
    for (int j = 1; j <= 3; ++j) { // 内层循环控制列
        cout << i << "*" << j << "=" << (i * j) << "\t";
    }
    cout << endl; // 每行结束后换行
}

2. `break` 和 `continue` 语句

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

3. C++ 标准库算法 (``)

标准库提供了许多基于循环思想的高级算法,如 `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;