Initial commit: C++ courseware

This commit is contained in:
xiaolinquan committed 2026-11-05 22:51:02 +08:00
commit 4a4ee7c287
1789 files changed
+373489

No files matched your search

@@ -0,0 +1,89 @@
### **C++ 讲义:多分支选择 (`if-else if-else`)**
#### **一、 处理“多选一”与“互斥”**
**1.1 从二元选择到多元选择**
我们已经掌握了:
* **`if` 结构(单分支)**:解决“做或不做”的问题。
* **`if-else` 结构(双分支)**:解决“二选一”的问题。
然而,程序设计中的决策往往涉及三个或更多的选项。`if-else if-else` 结构正是为了解决这类**多选一**的场景而设计的。理解该结构的关键,在于深刻理解**“互斥”**这一概念。
**1.2 “互斥”:`if-else if-else` 的适用点**
* **互斥场景(适用 `if-else if-else`):交通信号灯**
交通信号灯的状态是典型的互斥关系:在任何特定时刻,交通灯只能处于其中一种状态(红、黄、绿),绝不可能同时既是红灯又是绿灯。**当面临必须“多选一”的排他性选项时,应使用多分支结构。**
* **非互斥场景(不适用多分支,应使用多个独立 `if`):自助餐取餐**
假设在自助餐厅,有烤鸡翅、牛排、三文鱼、沙拉四个选项。这些选项是不互斥的:你拿了烤鸡翅,并不会阻止你继续拿牛排和沙拉。这些条件可以同时成立。在这种“多选多”的场景下,必须使用多个独立的 `if` 语句来判断,不能使用 `else if`(因为 `else if` 一旦命中一个,就会跳过后续所有选项)。
#### **二、 语法结构与执行流程**
**2.1 语法结构与规则**
```cpp
if (条件1) {
// 仅当 条件1 成立时执行
} else if (条件2) {
// 当 条件1 不成立,且 条件2 成立时执行
} else if (条件n) {
// ... 可以根据需要添加任意多个 else if 分支 ...
} else {
// 当以上所有条件都不成立时,执行此保底操作 (此分支可省略)
}
```
**结构非常灵活:**
* **`else if` 可以有无限个**:根据实际决策的需要,你可以在 `if` 之后添加任意多个 `else if` 分支,以覆盖所有可能的互斥选项。
* **`else` 是可以省略的**:最后的 `else` 分支并非强制要求。如果省略了 `else`,且上方所有的 `if` 和 `else if` 条件评估均为 `false`,程序将直接跳过整个多分支结构,不执行其中的任何代码,继续向下运行。
**2.2 执行顺序**
1. **自上而下,顺序判断**:程序会严格按照从上到下的顺序,逐一评估每个 `if` 或 `else if` 的条件。
2. **首次命中,立即跳出**:一旦某个条件被评估为 `true`,程序将执行其对应的代码块。执行完毕后,**立即跳出整个多分支结构**,后续所有的 `else if` 和 `else` 分支都会被忽略。
3. **`else` 隐含的条件**:每一个 `else if` 语句都隐含了一个前提——**它前面的所有 `if` 和 `else if` 条件均为 `false`**。这是编写简洁代码的关键。
#### **三、 实战:BMI 肥胖问题评估 (书本P40 例3-7)**
**3.1 任务目标**
根据输入的体重 `m` (kg) 和身高 `h` (m),计算身体质量指数 `BMI = m / (h * h)`,并根据以下规则输出结果:
* **规则1**:BMI < 18.5,输出 "Underweight"。
* **规则2**:18.5 <= BMI < 24,输出 "Normal"。
* **规则3**:BMI >= 24,输出 BMI 数值并换行输出 "Overweight"。
**3.2 代码实现与逻辑分析**
```cpp
int main() {
double m, h, bmi;
cin >> m >> h;
bmi = m / (h * h);
if (bmi < 18.5) {
cout << "Underweight";
} else if (bmi < 24) { // 利用隐含的条件简写为 bmi < 24
cout << "Normal";
} else { // 兜底选项
cout << bmi << endl;
cout << "Overweight";
}
return 0;
}
```
**3.3 代码解读**
在判断“正常”范围时,我们**没有写** `else if (bmi >= 18.5 && bmi < 24)`,而是简写为 `else if (bmi < 24)`。
**原因**:正是利用了多分支结构的**“隐含条件”**特性。程序能执行到这个 `else if`,必然是因为第一个 `if (bmi < 18.5)` 判断为假。因此,被筛选到第二层的 BMI 数据,已经天然满足了 `bmi >= 18.5` 这个条件,无需再次判断,使得代码更简洁。
#### **四、 知识点总结**
1. **明确结构适用性**:
处理多个且选项之间**完全互斥**的决策时,使用 `if-else if-else`。处理选项可共存(如自助餐)的决策时,必须使用多个独立的 `if`。
2. **结构灵活**:
一个多分支结构由 1个 `if` 起头,中间可以有 **0个或任意多个** `else if`,结尾可以有 **0个或1个** `else` 组成。虽然语法上 `else` 可以省略,但建议保留作为“保底”机制,处理其他所有未被匹配到的情况。
3. **重视书写顺序**:
在多分支结构中,通常应优先将**最严格、最特殊**的条件放在前面,并善于利用结构自带的隐含的条件来精简后续的判断逻辑。
@@ -0,0 +1,93 @@
### **C++ 讲义:`if` 条件嵌套**
#### **一、判断中的再判断**
当一个判断逻辑过于复杂,无法通过单一层级的 `if-else if-else` 有效解决时,需要引入一种更强大的结构——**条件嵌套**。
* **定义**:**在一个 `if`、`else if` 或 `else` 的 `{}` 代码块内部,再放入另一个完整的 `if` 结构**,这就构成了条件嵌套。
* **核心思想**:它映射了人类解决复杂问题时的“分步决策”的思维模式。**外层 `if` 负责确定一个大的前提或类别,而内层 `if` 则在此外层前提下,处理更细分的子问题。**
通过嵌套,我们可以将一个复杂的大问题变成了一系列更简单的小问题。
#### **二、语法结构与执行流程**
##### **2.1 基本语法**
条件嵌套的本质,就是将一个 `if` 语句块作为另一个 `if` 语句块的执行内容。
```cpp
if (外层条件) {
// 外层条件成立后,进入此代码块
if (内层条件) {
// 当 外层条件 和 内层条件 同时成立时,执行这里的代码
} else {
// 当 外层条件 成立,但 内层条件 不成立时,执行这里的代码
}
} else { // 注意这里的 else 匹配的是 if (外层条件)
// 当 外层条件 不成立时,执行此代码块
// 这里也可以继续嵌套...
}
```
##### **2.2 执行流程解析**
计算机在执行嵌套结构时,遵循“**由外到内,层层把关**”的原则:
1. **判断外层条件**:首先,只看最外层的 `if` 条件。
2. **决定是否进入**:
* 如果外层条件为 `false`,程序将直接跳过整个外层 `{}` 代码块,不会去检查内层的 `if` 条件。
* 如果外层条件为 `true`,程序才会进入外层代码块中,并开始判断内层的 `if` 条件。
3. **判断内层条件**:进入内层后,判断内层的 `if-else` 结构,根据条件的真假来决定执行哪个子分支。
#### **三、基础用法与实例**
##### **3.1 场景一:会员等级与消费金额折扣**
**需求**:一个商场打折规则如下:
* 必须是会员才能享受折扣,并且会员如果消费满 500 元,打 8 折;如果消费不满 500 元,打 9 折。
* 非会员不打折。
**分析**:
* **外层判断**:首要前提是“是否为会员?”
* **内层判断**:在“是会员”这个大前提下,再细分“消费金额是否满500?” 的条件。
**代码实现**:
```cpp
bool is_member = true;
double total_cost = 600.0;
if (is_member == true) {
// 代码能进入此区域,说明此人一定是会员
cout << "尊贵的会员您好" << endl;
if (total_cost >= 500) {
// 会员,且消费满500
cout << "享受8折优惠!" << endl;
} else {
// 会员,但消费未满500
cout << "享受9折优惠!" << endl;
}
} else {
// 代码没有进入此区域,说明此人一定不是会员
cout << "抱歉,非会员不参与打折活动。" << endl;
}
```
##### **3.2 场景二:三数排序 (书本例3-5)**
**任务**:输入三个整数 `a, b, c`,将它们从大到小排序输出。
**分析**:
* **外层判断**:先确定三个数中最大的那个数是谁(三选一)。
* **内层判断**:在最大数确定的前提下,只需比较剩下两个数的大小(二选一)。
**代码实现参见书本例3-5,本处略。**
#### **四、总结**
1. **嵌套构建复杂逻辑**:当单一维度的判断不足以解决问题时,使用 `if` 嵌套结构来处理“层层递进”的判断。
2. **分治思想的体现**:条件嵌套是一种“分而治之”的思想。外层 `if` 解决主要矛盾,内层 `if` 解决次要矛盾,从而将复杂问题分解。
3. **提升代码可读性**:良好的嵌套结构能让代码逻辑与人类的自然思考过程保持一致,是编写高质量、可维护代码的重要技巧。
4. **注意代码缩进**:在编写嵌套代码时,必须使用规范的缩进,以清晰地展示代码的层级关系,否则代码将变得难以阅读和维护。
@@ -0,0 +1,34 @@
### **参考答案**
#### **一、 填空题**
1. 多选一
2. 多分支, 一
3. 保底, 不满足
4. 条件嵌套 (或 嵌套分支 / 分支嵌套)
5. 严格, 特殊
#### **二、 单项选择题**
1. **B** (会先检查更高优先级的规则)
2. **C** (score=85 满足 `>=60`,执行后跳出整个结构)
3. **BC** (这是对 `if-else if-else` 完整性最准确的描述)
4. **A** (`x > 3` 成立,输出"A";接着 `y < 5` 不成立,执行内层 `else`,输出"C")
5. **A** (一旦第一个条件满足,就不会再检查后面的 `else if`)
6. **B** (讲义优点部分明确指出:逻辑清晰,代码结构反映了分步解决的思考过程)
7. **C** (这是对 `else if` 最核心的理解,体现了它的“否则,如果...”)
8. **C** (`else` 后面不能也不需要带条件判断)
9. **B** (外层分支的目的就是找出最大的数)
10. **A** (`num=8`时,A选项的 `num<5` 和 `num<8` 都不满足,执行 `else`;B选项的 `num>8` 不满足,执行 `else`;C选项 `num==8` 满足,输出B;D选项都不满足,执行`else`)
#### **三、 判断题**
1. **×** (一旦满足条件,就会跳出整个结构,不再检查后续分支)
2. **√** (这是一个 `if-else if-else` 结构的语法规则)
3. **×** (`if` 可以单独存在,`else` 和 `else if` 都是可选的)
4. **√** (这就是条件嵌套的定义)
5. **×** (顺序至关重要。如果交换,当输入12时,`if(x > 5)`会先被满足,逻辑就错了)
6. **√** (讲义中明确指出了这两种解法的优缺点)
7. **√** (这是两个独立的 `if` 语句,不是 `if-else if` 结构。两个条件都满足,所以都会执行)
8. **√** (这是 `else if` 的核心逻辑)
9. **√** (讲义中明确提到,嵌套解法反映了“分步解决”的思考过程)
10. **×** (执行块内都可以嵌套,`if`, `else if`, `else` 的代码块内均可)
@@ -0,0 +1,100 @@
### **C++ `if` 的多分支与条件嵌套 课后习题**
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
#### **一、 填空题**
1. `if-else` 结构主要解决“**二选一**”的问题,而 `if-else if-else` 结构则解决了“**\_\__\_\_\_\_\_\_**”的问题。
2. `if-else if-else` 结构也被称为 **\_\_\_\__\_\_\_\_\_\_\_** 结构,它的核心特点是“择一执行”,即整个结构中最多只有 **\_\_\__\_\_\_\_\_\_\_\_** 个代码块会被执行。
3. 在 `if-else if-else` 结构中,`else` 关键字的作用是作为“**\_\_\__\_\_\_\_\_\_\_\_**”选项,当所有 `if` 和 `else if` 的条件都**\_\__\_\_\_\_\_\_\_\_\_** (填写“满足”或“不满足”)时,它的代码块才会被执行。
4. 将一个 `if` 语句完整地放入另一个 `if` 或 `else` 语句的执行代码块中,这种结构被称为 **\_\__\_\_\_\_\_\_\_\_\_\_\_\_\_**。
5. 在编写 `if-else if-else` 结构时,为了保证逻辑的正确性,通常应该将范围最**\_\_\_\_\_\_\__\_\_\_\_**、最**\_\__\_\_\_\_\_\_\_\_\_**的条件放在最前面。
#### **二、 单项选择题**
( ) 1. 根据课程和讲义中酒店保安的例子,如果来了一位“普通VIP”,保安的决策流程是怎样的?
A. 直接跳到“普通VIP”规则,并带他去二层 B. 先判断他是不是顶级VIP,如果不是,再判断他是不是普通VIP
C. 同时判断他是不是 顶级VIP 和 普通VIP D. 检查完所有规则后,才决定带他去二层
( ) 2. 观察以下代码片段,当 `int score = 85;` 时,程序的输出是什么?
```cpp
if (score >= 90) {
cout << "优秀" << endl;
} else if (score >= 60) {
cout << "及格" << endl;
} else {
cout << "不及格" << endl;
}
```
​ A. 优秀 B. 良好 C. 及格 D. 不及格
( ) 3. 关于 `if-else if-else` 结构的执行,以下说法正确的是?
A. 只要有条件满足,所有代码块都会被执行 B. 至少有一个代码块会被执行
C. 如果有 `else`,保证有且仅有一个代码块被执行 D. 可能会有多个 `else if` 的代码块被同时执行
( ) 4. 对于定义了变量 `int x = 5, y = 10;` 运行以下代码,输出结果是什么?
```cpp
if (x > 3) {
cout << "A";
if (y < 5) {
cout << "B";
} else {
cout << "C";
}
} else {
cout << "D";
}
```
​ A. AC B. AB C. D D. A
( ) 5. 对于代码 `if (a > 10) { ... } else if (a > 5) { ... }`,如果变量 `a` 的值是 `12`,哪个代码块会被执行?
A. `if (a > 10)` 对应的代码块 B. `else if (a > 5)` 对应的代码块
C. 两个代码块都会被执行 D. 两个代码块都不会被执行
( ) 6. 在三数排序的案例中,相对于“纯粹的多分支判断”,“嵌套分支”解法的主要优点是?
A. 代码行数更少 B. 逻辑更清晰,将复杂问题分步解决
C. 运行效率更高 D. 使用的关键字更少
( ) 7. 从字面和逻辑上理解,`else if (表达式)` 的含义最准确的是?
A. 并且,如果 表达式 成立 B. 或者,如果 表达式 成立
C. 在前面的所有条件都不成立的前提下,如果 表达式 成立
D. 无论如何,检查 表达式 是否成立
( ) 8. 关于 `if-else if-else` 结构中最后的 `else` 部分,下列哪个说法是**错误**的?
A. 它是可选的,可以不写 B. 它用于处理所有 `if` 和 `else if` 条件都不满足的情况
C. 它必须带一个条件判断,例如 `else (表达式)` D. 加上它可以让程序处理之前的所有条件都不满足的情况
( ) 9. 当我们比较三个数字的时候,当程序执行到 `if (a >= b && a >= c)` 的内部代码块时,如下的判断哪个是正确的?
A. a 是三个数中最小的 B. a 是三个数中最大的
C. a, b, c 三个数完全相等 D. b 和 c 的大小关系已经确定
( ) 10. 给定代码 `int num = 8;`,以下哪个 `if` 结构会输出 "C"?
A. `if(num<5){cout<<"A";} else if(num<8){cout<<"B";} else{cout<<"C";}`
B. `if(num>10){cout<<"A";} else if(num>8){cout<<"B";} else{cout<<"C";}`
C. `if(num>9){cout<<"A";} else if(num==8){cout<<"B";} else{cout<<"C";}`
D. `if(num<0){cout<<"A";} else if(num>10){cout<<"B";} else{cout<<"C";}`
#### **三、 判断题 (对的打“√”,错的打“×”)**
( ) 1. 在一个 `if-else if-else` 结构中,如果第一个 `if` 的条件为真,程序会会继续检查后面的 `else if` 条件。
( ) 2. `if-else if-else` 结构中,`else if` 可以有很多个,但 `if` 和 `else` 最多只能有1个。
( ) 3. 一个 `if` 结构必须包含 `else` 部分,否则代码会编译失败。
( ) 4. 在 C++ 中,`if` 语句的执行块内可以再包含另一个完整的 `if-else` 结构。
( ) 5. 对于 `if (x > 10) { ... } else if (x > 5) { ... }` 这样的结构,条件 `x > 10` 和 `x > 5` 的顺序可以随意交换,不会影响程序的逻辑结果。
( ) 6. 三数排序案例中,解法一(纯粹使用多分支判断)的优点是逻辑简单,但缺点是存在重复判断。
( ) 7. 对于代码 `int num = 10; if (num > 5) { cout << "A"; } if (num > 8) { cout << "B"; }`,屏幕上会输出 "AB"。
( ) 8. `else if` 中的 `else` 关键字,其隐含了:在此之前的所有 `if` 和 `else if` 的条件判断结果均为 `false`。
( ) 9. 用嵌套分支解决三数排序问题,体现了“我们人类的分步解决”的思想,理解起来会更容易。
( ) 10. `if` 语句只能嵌套在另一个 `if` 语句的代码块中,不能嵌套在 `else` 的代码块中。