5、流程控制语句:程序的“交通指挥员”

流程控制语句,说白了就是告诉程序“下一步该往哪走”。

没有它们,代码只能从上往下一条条执行,跟念流水账似的。有了它们,程序才有了“智能”——能判断、能循环、能跳转。

我个人习惯把流程控制比作十字路口的红绿灯。if-else 是“如果绿灯就走,红灯就停”;while 是“只要没撞到人,就一直开”;for 是“跑完这 10 圈就收工”。

嗯,咱们一个一个来看。

流程控制语句知识体系 分支结构 if-else switch-case 循环结构 while 循环 do-while 循环 for 循环 跳转控制 break continue goto(慎用) 三大类:分支 → 循环 → 跳转,构成了所有程序的逻辑骨架 goto 已用虚线标出 —— 能不用就不用

if-else 判断:最基础的分支

if-else 是 C++ 里最常用的判断语句。它的逻辑很简单:如果条件成立,做 A;否则做 B

int score = 85;
if (score >= 60) {
    cout << "及格了" << endl;
} else {
    cout << "不及格" << endl;
}

你想想看,这跟现实中的决策一模一样。比如“如果下雨,带伞;否则不带”。

我的习惯:写 if-else 时,我总是把最可能成立的条件放在最前面。这样程序能更快地“找到出口”,性能会好一点点。虽然差别不大,但积少成多。

多分支的情况,可以用 else if 串联:

if (score >= 90) {
    cout << "优秀";
} else if (score >= 80) {
    cout << "良好";
} else if (score >= 60) {
    cout << "及格";
} else {
    cout << "不及格";
}
注意:else 总是与最近的 if 配对。如果你写了嵌套 if,记得用大括号明确范围。我曾经见过一个 bug,就是因为少写了大括号,导致 else 匹配错了 if,排查了整整一下午。

switch-case 分支:多路选择的利器

当你要判断的变量是整型、字符型或枚举型,而且分支比较多时,switch-case 比 if-else 更清晰。

char grade = 'B';
switch (grade) {
    case 'A':
        cout << "优秀";
        break;
    case 'B':
        cout << "良好";
        break;
    case 'C':
        cout << "及格";
        break;
    default:
        cout << "未知等级";
        break;
}

这里有个关键点:别忘了写 break。如果不写,程序会“穿透”到下一个 case 继续执行。这叫“fall-through”。

避坑指南:我曾经在写一个协议解析模块时,忘了在某个 case 后面加 break,结果程序一路穿透下去,把后面的所有 case 都执行了一遍。那个 bug 藏了三天才被发现。所以我现在写 switch-case,第一件事就是检查每个 case 有没有 break。

不过,fall-through 有时候也有用。比如多个 case 共享同一段逻辑:

switch (ch) {
    case 'a': case 'e': case 'i': case 'o': case 'u':
        cout << "元音字母";
        break;
    default:
        cout << "辅音字母";
        break;
}

while 循环:先判断,后执行

while 循环的逻辑是:只要条件为真,就一直执行循环体。如果一开始条件就不成立,循环体一次都不执行。

int i = 0;
while (i < 5) {
    cout << i << " ";
    i++;
}
// 输出:0 1 2 3 4

我个人习惯用 while 来处理“不知道要循环多少次”的场景。比如读取文件直到结束:

while (!file.eof()) {
    // 读取一行数据
}
死循环警告:如果你忘了在循环体内改变条件变量(比如上面的 i++),程序就会永远跑下去。我见过有人写 while(1) 然后忘了写 break,CPU 直接飙到 100%。嗯,那场面挺尴尬的。

do-while 循环:先执行,后判断

do-while 和 while 的区别只有一个:do-while 至少执行一次循环体

int i = 0;
do {
    cout << i << " ";
    i++;
} while (i < 5);
// 输出:0 1 2 3 4

什么时候用 do-while?比如你要先显示一次菜单,再根据用户选择决定是否继续:

char choice;
do {
    cout << "1. 查询余额\n2. 取款\n3. 退出\n";
    cin >> choice;
    // 处理选择...
} while (choice != '3');

你想想看,如果这里用 while,你得在循环外面先打印一次菜单,代码就冗余了。do-while 正好解决这个问题。

for 循环:最常用的循环

for 循环把初始化、条件判断、变量更新都写在一行里,结构紧凑,是 C++ 里最常用的循环。

for (int i = 0; i < 5; i++) {
    cout << i << " ";
}
// 输出:0 1 2 3 4

它的执行顺序是:

  1. 执行初始化(只执行一次)
  2. 判断条件是否成立
  3. 如果成立,执行循环体
  4. 执行更新语句
  5. 回到第 2 步
我的习惯:遍历数组或容器时,我几乎只用 for 循环。配合 C++11 的 range-based for,代码更简洁:
vector<int> vec = {1, 2, 3, 4, 5};
for (int v : vec) {
    cout << v << " ";
}

break 与 continue:循环的“刹车”和“跳过”

break:立即跳出当前循环,不再执行后续的迭代。

continue

for (int i = 0; i < 10; i++) {
    if (i == 5) break;    // i 等于 5 时跳出循环
    if (i % 2 == 0) continue; // 偶数跳过,不打印
    cout << i << " ";
}
// 输出:1 3

break 和 continue 的区别,说白了就是:break 是“我不干了”,continue 是“这次不算,重来”

避坑指南:嵌套循环里,break 只跳出它所在的那一层循环。如果你想跳出多层循环,要么用 goto,要么用标志变量。我个人推荐用标志变量,因为 goto 容易让代码变得像意大利面条一样乱。

goto 语句:慎用,但别完全否定

goto 可以让你无条件跳转到程序中的任意位置。听起来很强大,对吧?但代价是代码的可读性会急剧下降。

int i = 0;
loop:
    cout << i << " ";
    i++;
    if (i < 5) goto loop;
// 输出:0 1 2 3 4

你看,用 goto 也能实现循环,但代码的流程变得很难追踪。尤其是当 goto 跳来跳去的时候,读代码的人会疯掉。

我的建议:99% 的情况下,不要用 goto。但如果你遇到“从深层嵌套中一次性跳出”的场景,而且用标志变量会让代码更复杂,那么 goto 可以作为一个“最后的武器”。我在 Linux 内核源码里见过 goto 的合理使用——用于统一的错误处理和资源清理。但那是高手玩的,初学者还是老老实实用 break 和 continue 吧。

说白了,goto 就像一把刀。用好了能切菜,用不好会切到手。在你还没成为“厨神”之前,先把它收起来。


好了,流程控制语句就讲到这里。这些是 C++ 编程的“骨架”,所有复杂的逻辑都建立在它们之上。多写、多练,慢慢你就会发现——其实它们没那么神秘。

一句话总结:if-else 做判断,switch-case 选多路,while/for 搞循环,break/continue 控节奏,goto……嗯,先忘掉它。
专注资料整理
专注资料整理