搜索

C++ 教程

C++基础

第1章 搭建开发环境与第一个程序 第2章 基本数据类型与变量 第3章 运算符与表达式 第4章 流程控制语句 第5章 数组与字符串 第6章 函数基础 第7章 指针基础 第8章 引用与const限定 第9章 动态内存管理 第10章 结构体与联合体 第11章 函数进阶

面向对象

第12章 面向对象编程入门 第13章 封装与访问控制 第14章 运算符重载 第15章 继承与派生 第16章 多态与虚函数

STL与进阶

第17章 模板编程基础 第18章 标准模板库(STL)容器 第19章 STL算法与迭代器 第20章 异常处理机制 第21章 文件输入输出 第22章 字符串类string 第23章 命名空间与作用域 第24章 类型转换操作符

现代C++

第25章 智能指针 第26章 移动语义与右值引用 第27章 Lambda表达式 第28章 多线程编程基础 第29章 模板元编程入门 第30章 设计模式基础 第31章 C++11/14新特性 第32章 C++17/20核心特性

实战进阶

第33章 性能优化技巧 第34章 调试与测试 第35章 项目结构与构建 第36章 网络编程入门 第37章 数据库连接操作 第38章 图形界面开发基础 第39章 综合项目实战 第40章 进阶学习路线

第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 对比
特性if-elseswitch
判断条件可以是任意布尔表达式(关系、逻辑运算)只能是整型或枚举类型的相等比较
适用场景条件复杂、范围判断、非等值比较针对单一变量的多个离散值进行等值匹配
代码结构灵活,可嵌套清晰,呈并列结构
性能通常顺序判断,条件多时可能较慢编译器可能优化为跳转表,多分支时效率高

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 循环的标准执行流程:

初始化 (int i=1)
→
条件判断 (i<=10?)
→
循环体 (cout << i)
→
迭代更新 (++i)

如果条件判断为假,循环立即终止,不会执行循环体和迭代更新。

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,尝试完成以下任务:

  1. 编写一个程序,使用 for 循环输出斐波那契数列的前20项(斐波那契数列:F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2))。
  2. 模拟一个简单的登录系统。预设用户名 "admin" 和密码 "123456"。使用 do-while 循环,允许用户最多尝试3次登录。每次尝试后提示剩余次数,登录成功或尝试次数用尽后退出循环。
  3. (挑战)使用嵌套循环打印一个如下所示的直角三角形图案:
    *
    **
    ***
    ****
    *****

检验你的理解

  1. 下面这段代码的输出是什么?先思考,再运行验证。
    int x = 5;
    while (x-- > 0) {
        if (x == 2) continue;
        cout << x << " ";
    }
  2. 以下两种循环写法,哪种更优?为什么?
    // 写法A
    for (int i = 0; i < strlen(someString); ++i) { ... }
    
    // 写法B
    int len = strlen(someString);
    for (int i = 0; i < len; ++i) { ... }
  3. 如果 switch 语句中某个 case 后面忘了写 break,会发生什么?请举例说明。

本章小结

  • 条件分支是程序决策的基础: if-else 处理复杂的布尔逻辑,switch 针对单一变量的离散值进行清晰的多路选择,务必注意每个 case 后的 break。
  • 三种循环各有其适用场景: 已知循环次数用 for;未知次数但需先判断条件用 while;至少需执行一次循环体用 do-while。
  • 精细控制循环流程: break 用于立即终止整个循环,continue 用于跳过本次循环的剩余部分,直接开始下一次迭代。
  • 警惕常见陷阱: 避免条件判断中的赋值运算符误用、switch 的case穿透、以及因循环条件永远为真导致的死循环。
  • 组合运用是关键: 在实际编程中,条件语句和循环语句经常嵌套使用,以解决复杂的逻辑问题。

意见反馈

微信二维码 微信扫码关注 抖音二维码 抖音扫码关注