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 循环、算法库和并行执行策略,让循环操作更加简洁和高效。