需要重复处理一组数据时,C++ 日常代码优先用范围 for 遍历 std::vector 或 std::string;次数未知或由流状态驱动时再用 while;下标、步长明确时用计数 for;必须先执行循环体、再决定是否继续时用 do-while。本节说明这几种写法的适用场景,以及循环停不下来、下标多走一次或少走一次这类常见问题。

范围 for(推荐遍历容器)

不必手写下标与长度,由编译器按元素迭代,见范围 for:

C++ 范围 for 遍历 vector运行
#include <iostream>
#include <vector>

int main() {
    std::vector<int> scores{90, 85, 88};
    int sum = 0;
    for (int s : scores) {
        sum += s;
    }
    std::cout << sum << "\n";
    return 0;
}

输出:

263

需要改元素时写 for (int& s : scores);只读大对象用 const auto&。

while:条件未知次数

每次迭代前判断条件。循环体必须推进状态,否则可能死循环。读入直到流失败:while (std::cin >> value)。

开始条件?真循环体假循环后代码结束

while 先判断条件:为真执行循环体再回到条件;为假离开循环。

int n = 5;
while (n > 0) {
    std::cout << n << " ";
    --n;
}

计数 for

初始化、条件、更新写在同一行,适合下标或固定次数。循环变量声明在 for 内时,作用域不泄漏到循环外:

开始初始化 ii < n?真循环体i++假循环后代码结束

for 先初始化,再判断条件;体执行完后做 i++,再回到条件。

int sum = 0;
for (int i = 1; i <= 10; ++i) {
    sum += i;
}

遍历 vector 时仍更宜范围 for。必须用下标时,合法下标是 0 到 v.size() - 1,因此条件写 i < v.size()。若写成 i <= v.size(),最后一次会访问不存在的 v[v.size()],比实际元素多走一次。反过来,求 1 到 10 的和却写成 i < 10,则少加了 10。这类边界写错,循环次数会比预期多一次或少一次。size() 的类型是无符号整数,与负数比较时更容易判断反。

do-while

do-while 先执行循环体,再判断条件:条件为真则再执行一次,为假则离开。因此即使条件一开始就不成立,循环体也会执行一遍;同样情况下 while 一次也不会进入。

开始循环体条件?真假循环后代码结束

do-while 先执行循环体,再判断条件:为真回到循环体,为假离开。

C++ do-while 至少执行一次运行
#include <iostream>

int main() {
    int n = 0;
    do {
        std::cout << n << "\n";
    } while (n > 0);
    return 0;
}

输出:

0

因为 n 是 0,所以条件 n > 0 不成立;但循环体已经执行过,因此仍打印 0。若改成 while (n > 0) { ... },则什么也不打印。while (...) 后面的分号是整条 do-while 语句的结束,不能省略。

菜单、确认输入这类至少要问一次的场景,适合用 do-while:

char ans;
do {
    std::cout << "继续?(y/n) ";
    std::cin >> ans;
} while (ans == 'y' || ans == 'Y');

对照

形式优先场景
范围 for遍历容器或数组的每个元素
while结束条件由数据或流决定
计数 for需要下标或固定次数
do-while必须先执行再问是否继续

条件恒真且体内无退出路径会占满 CPU。教学可用 while (true) 配合 break;实际代码应保证终止条件可达。

本节说明了 C++ 中更常用的循环写法。下一节介绍break 与 continue。