第4章 流程控制语句
第4章 流程控制语句
- 使用if/else和switch进行条件判断
- 使用for、while、do-while进行循环控制
- 使用break和continue控制循环流程
想象一下十字路口的红绿灯,它根据“红灯停、绿灯行”的规则指挥交通。C++的流程控制语句就是程序的“交通规则”,它决定了代码执行的路径和次数。没有它们,程序只能从上到下机械地执行,无法应对复杂的现实逻辑。
4.1 条件分支:程序的选择题
条件分支让程序能够根据不同的情况做出选择。最核心的两个工具是 if-else 和 switch。
4.1.1 if-else语句:基础的条件判断
这是最常用、最直观的条件判断语句。它的结构就像“如果...就...否则...”。
int score = 85;
if (score >= 60) {
cout << "恭喜,考试通过!" << endl;
} else {
cout << "很遗憾,需要补考。" << endl;
}
你可以使用 else if 来处理多个条件。实际开发中,我见过新手常犯的错误是条件判断的顺序不合理,导致某些分支永远无法执行。
常见误区
- 条件重叠: 在多个 else if 中,条件范围有重叠,导致逻辑混乱。
- 误用赋值运算符: 将 if (a == 5) 写成 if (a = 5),后者是赋值操作,条件永远为真。
- 遗漏花括号: 当if或else后只有一条语句时,花括号可以省略,但为了代码清晰和避免后续修改出错,我强烈建议始终加上花括号。
4.1.2 switch语句:多路分支选择
当需要根据一个变量的不同值执行不同操作时,switch 比一连串的 else if 更清晰。它就像一个多档位的开关。
int dayOfWeek = 3;
switch (dayOfWeek) {
case 1:
cout << "Monday" << endl;
break;
case 2:
cout << "Tuesday" << endl;
break;
case 3:
cout << "Wednesday" << endl;
break;
default:
cout << "Invalid day" << endl;
break;
}
switch 只能用于整型(int, char, enum)或能隐式转换为整型的表达式。每个 case 后面的 break 至关重要,它用于跳出整个 switch 块。如果忘记写,程序会“穿透”到下一个 case 继续执行,这有时是故意设计的技巧,但对新手来说通常是bug。
| 特性 | if-else | switch |
|---|---|---|
| 判断条件 | 可以是任意布尔表达式(关系、逻辑运算) | 只能是整型或枚举类型的相等比较 |
| 适用场景 | 条件复杂、范围判断、非等值比较 | 针对单一变量的多个离散值进行等值匹配 |
| 代码结构 | 灵活,可嵌套 | 清晰,呈并列结构 |
| 性能 | 通常顺序判断,条件多时可能较慢 | 编译器可能优化为跳转表,多分支时效率高 |
4.2 循环语句:重复的力量
循环语句用于重复执行一段代码,直到满足某个终止条件。这就像洗碗,你需要重复“擦洗-冲洗”的动作,直到所有碗都干净。C++提供了三种主要的循环结构。
4.2.1 for循环:计数型循环
for 循环最适合在已知循环次数的情况下使用。它的结构非常紧凑,将初始化、条件判断和迭代更新集中在一行。
// 打印数字1到10
for (int i = 1; i <= 10; ++i) {
cout << i << " ";
}
这里有个隐藏的坑:循环变量 i 的作用域。在C++98标准中,i 在 for 循环外仍然可见,这容易导致命名冲突。从C++11开始,在 for 语句内声明的变量,其作用域被限定在循环体内,这是更安全的做法。
循环控制流程图
理解循环的执行顺序是避免死循环的关键。下面展示了 for 循环的标准执行流程:
如果条件判断为假,循环立即终止,不会执行循环体和迭代更新。
4.2.2 while与do-while循环:条件型循环
当你不知道具体要循环多少次,只知道循环条件时,应该使用 while 或 do-while。
// while循环:先判断,后执行
int userInput = -1;
while (userInput != 0) {
cout << "请输入一个数字(0退出): ";
cin >> userInput;
cout << "你输入了: " << userInput << endl;
}
// do-while循环:先执行一次,再判断
int choice;
do {
cout << "1. 开始游戏\n2. 加载存档\n3. 退出\n请选择: ";
cin >> choice;
// ... 处理choice ...
} while (choice != 3); // 选择3才退出
while 可能一次都不执行,而 do-while 至少会执行一次。在需要至少执行一次的场景(如菜单显示),do-while 是更自然的选择。
编者提示: 循环中经常需要处理用户输入或数据集合。关于如何高效地存储和遍历一组数据(比如所有学生的成绩),我们将在第5章《数组与字符串》中详细讲解,届时你会看到循环与数组结合的强大威力。
4.3 流程跳转:break与continue
这两个关键字用于在循环内部进行更精细的控制,它们改变了循环的正常流程。
break
- 作用: 立即终止整个循环(或switch语句)。
- 场景: 在数组中查找元素,找到后立即退出循环。
continue
- 作用: 跳过本次循环剩余的语句,直接进入下一次循环的条件判断。
- 场景: 处理一批数据时,跳过不符合条件的数据。
来看一个结合使用的例子,这个模式在实际项目中很常见:
// 计算1到100之间所有非7的倍数的奇数之和
int sum = 0;
for (int num = 1; num <= 100; ++num) {
if (num % 2 == 0) {
continue; // 跳过偶数
}
if (num % 7 == 0) {
continue; // 跳过7的倍数
}
if (sum > 1000) {
break; // 总和超过1000就提前终止
}
sum += num;
}
cout << "计算结果: " << sum << endl;
记住,break 只能跳出一层循环或switch。如果你在嵌套循环的最内层使用 break,它只会跳出当前这一层循环,外层循环继续执行。
动手试一试
打开你的IDE,创建一个新文件 control_practice.cpp,尝试完成以下任务:
- 编写一个程序,使用 for 循环输出斐波那契数列的前20项(斐波那契数列:F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2))。
- 模拟一个简单的登录系统。预设用户名 "admin" 和密码 "123456"。使用 do-while 循环,允许用户最多尝试3次登录。每次尝试后提示剩余次数,登录成功或尝试次数用尽后退出循环。
- (挑战)使用嵌套循环打印一个如下所示的直角三角形图案:
* ** *** **** *****
检验你的理解
- 下面这段代码的输出是什么?先思考,再运行验证。
int x = 5; while (x-- > 0) { if (x == 2) continue; cout << x << " "; } - 以下两种循环写法,哪种更优?为什么?
// 写法A for (int i = 0; i < strlen(someString); ++i) { ... } // 写法B int len = strlen(someString); for (int i = 0; i < len; ++i) { ... } - 如果 switch 语句中某个 case 后面忘了写 break,会发生什么?请举例说明。
本章小结
- 条件分支是程序决策的基础: if-else 处理复杂的布尔逻辑,switch 针对单一变量的离散值进行清晰的多路选择,务必注意每个 case 后的 break。
- 三种循环各有其适用场景: 已知循环次数用 for;未知次数但需先判断条件用 while;至少需执行一次循环体用 do-while。
- 精细控制循环流程: break 用于立即终止整个循环,continue 用于跳过本次循环的剩余部分,直接开始下一次迭代。
- 警惕常见陷阱: 避免条件判断中的赋值运算符误用、switch 的case穿透、以及因循环条件永远为真导致的死循环。
- 组合运用是关键: 在实际编程中,条件语句和循环语句经常嵌套使用,以解决复杂的逻辑问题。
微信扫码关注
抖音扫码关注