第四章 流程控制:让程序会判断、会重复

← 返回目录

本章目标:if / else、switch、for、while、break、continue。 程序 99% 的逻辑都由它们组成。

4.1 if / else:做判断

int score = 85;
if (score >= 90) {
    std::println("优秀");
} else if (score >= 60) {
    std::println("及格");
} else {
    std::println("不及格");
}

规则:

4.2 [C++17] if 初始化语句(新写法,优雅)

C++17 允许在 if 条件里顺便声明变量:

if (int n = getCount(); n > 10) {
    std::println("数量很多:{}", n);
}
// 分号前的 n 只在 if 内可见,出了 if 就不存在了

好处:变量的作用域被限制在 if 内部,不会污染外面, 也不会出现"忘了重置旧值"的 bug。推荐使用。

4.3 switch:多分支选择

int day = 3;
switch (day) {
    case 1: std::println("周一"); break;
    case 2: std::println("周二"); break;
    case 3: std::println("周三"); break;
    default: std::println("其他"); break;
}

规则:

(这是故意的设计,但 99% 情况下是 bug 来源)

什么时候用 switch 而不是 if-else? 分支多且条件是"一个变量的几个固定值"时,switch 更清晰。

注意 C++17 里 switch 也能带初始化语句:

switch (int v = func(); v) { ... }

4.4 for 循环:数着次数重复

for (int i = 0; i < 5; ++i) {
    std::println("第 {} 次", i);
}
// 打印 第 0 次 ~ 第 4 次,共 5 次

拆解 for(初始化; 条件; 步进):

int i = 0;        // 1. 循环开始前,只执行一次
i < 5;            // 2. 每次循环前检查条件,假则退出
++i;              // 3. 每轮循环体结束后执行

执行顺序:1 → 2 → 体 → 3 → 2 → 体 → 3 → ... → 2(假)退出

常用变体: 1) 倒着数:for (int i = 10; i >= 0; --i) 2) 步长 2:for (int i = 0; i < 10; i += 2) 3) [C++11] 范围 for(最重要,强烈推荐):

   for (int x : numbers) { ... }

读作"对于 numbers 里的每一个 x"。遍历容器首选。 后面第七章和容器搭配使用。

4.5 while / do-while:条件满足就一直做

int i = 0;
while (i < 5) {          // 先检查,再执行
    std::println("{}", i);
    ++i;
}

do {                     // 先执行一次,再检查
    std::println("至少执行一次");
} while (false);

区别就一句话:while 先问后做;do-while 先做后问。

什么时候用 while?"不知道要循环几次,看条件"时。 比如读用户输入直到输入 q 退出:

std::string input;
while (std::cin >> input && input != "q") {
    // 处理 input
}

4.6 break / continue:提前退出或跳过

break;     // 立刻跳出当前整个循环(或 switch)
continue;  // 跳过本轮剩余部分,直接进入下一轮

例子:

for (int i = 0; i < 10; ++i) {
    if (i == 3) continue;   // 跳过 3
    if (i == 7) break;      // 到 7 就整个退出
    std::println("{}", i);  // 打印 0 1 2 4 5 6
}

注意:break 只跳出一层循环。多层循环嵌套时, 可以用 goto 或(更好的)用带标记的循环——不过新手阶段 遇到多层嵌套需要提前退出,先用"标志变量"最稳妥:

bool found = false;
for (int i = 0; i < n && !found; ++i) {
    for (int j = 0; j < m; ++j) {
        if (data[i][j] == target) { found = true; break; }
    }
}

4.7 死循环:会卡死的循环

while (true) { }        // 永远不结束
for (;;) { }            // 同上,老风格

死循环不是一定错——服务器、游戏主循环都是死循环, 但要保证里面有退出途径(break 或 return)。

典型 bug:循环变量忘更新:

int i = 0;
while (i < 10) { std::println("{}", i); }  // i 永远是 0!
// 条件永远为真 → 死循环(会刷屏,Ctrl+C 可以终止)

本章小结

练习题


  1. 用 for 打印 1 到 100,碰到 7 的倍数打印 "7倍数" 而不是数字。
  2. 用 while 实现"猜数字":随机数生成器先不学,

先用固定答案 42,循环读输入直到猜对。

  1. 用范围 for 遍历一个 vector(先写 vector<int> v{1,2,3};)

打印每个元素的平方。

  1. 打印九九乘法表(双层 for)。