Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
Binary file not shown.
Binary file not shown.
+214
@@ -0,0 +1,214 @@
|
||||
# **算术运算符与关系运算符**
|
||||
|
||||
#### 1. 引言
|
||||
|
||||
* **问题引入**:想象一下,你要编写一个游戏。角色的生命值被敌人攻击后会减少,捡到血包后会增加;你的得分会随着击败敌人而累加。这些“增加”、“减少”、“累加”的操作,在代码中如何实现呢?答案就是使用算术运算符。
|
||||
* **价值阐述**:算术运算符是编程的基石。无论是简单的数值计算、复杂的科学模拟,还是游戏开发中的逻辑处理,都离不开它们。掌握好算有运算符,是写出任何有意义程序的先决条件。
|
||||
|
||||
#### 2. 核心思想
|
||||
|
||||
* **思路铺垫**:我们从小学就开始学习数学中的“加减乘除”,C++ 中的算术运算符和它们的思想是完全一样的。它们接收一个或两个数值,然后给出一个计算结果。
|
||||
|
||||
* **算法精讲**:
|
||||
* **基本运算符**:`+`, `-`, `*`, `/`, `%` 这五个是我们最熟悉的。
|
||||
* `+` (加法): `5 + 2` 结果是 `7`
|
||||
* `-` (减法): `5 - 2` 结果是 `3`
|
||||
* `*` (乘法): `5 * 2` 结果是 `10`
|
||||
* `/` (除法): `5 / 2` 结果是 `2` (注意:整数除法会舍弃小数部分)
|
||||
* `%` (取模/取余): `5 % 2` 结果是 `1` (计算 `5` 除以 `2` 的余数)
|
||||
* **自增/自减运算符**:在编程中,"让一个变量加 1" 这个操作极其频繁。每次都写 `a = a + 1;` 会有点繁琐。于是,C++ 提供了一个更简洁、更高效的写法:`++` 和 `--`。
|
||||
* `++` (自增): 让变量的值加 1。`a++` 或 `++a` 都等价于 `a = a + 1`。
|
||||
* `--` (自减): 让变量的值减 1。`a--` 或 `--a` 都等价于 `a = a - 1`。
|
||||
|
||||
* **步骤拆解 (前置与后置的关键区别)**
|
||||
这是一个非常重要的知识点,也是初学者的一个难点。让我们把它拆解清楚:
|
||||
|
||||
* **前置**: `++a` 或 `--a`
|
||||
|
||||
1. **第一步:先**让变量 `a` 的值改变(加 1 或减 1)。
|
||||
2. **第二步:再**把 `a` **改变后**的新值,用于整个表达式的计算。
|
||||
* **口诀:先变,再用。**
|
||||
|
||||
* **后置**: `a++` 或 `a--`
|
||||
|
||||
1. **第一步:先**使用变量 `a` **原始的、未改变的**值,用于整个表达式的计算。
|
||||
2. **第二步:再**让变量 `a` 的值改变(加 1 或减 1)。
|
||||
* **口诀:先用,再变。**
|
||||
|
||||
#### 3. 实例
|
||||
|
||||
* **具体案例**:我们通过两个简单的 `cout` 输出来看看前置和后置的差别。
|
||||
|
||||
* **分步演示 1:前置 `++x`**
|
||||
```cpp
|
||||
int x = 5;
|
||||
cout << ++x << endl; // 我们想知道这里会输出什么
|
||||
```
|
||||
**计算机的执行过程**:
|
||||
1. 遇到 `++x`,这是一个前置自增。
|
||||
2. **第一步 (先变)**:`x` 的值从 `5` 变为 `6`。
|
||||
3. **第二步 (再用)**:使用 `x` 改变后的新值 `6` 来执行 `cout` 输出。
|
||||
4. **最终结果**:屏幕上输出 `6`。
|
||||
|
||||
**分步演示 2:后置 `y++`**
|
||||
|
||||
```cpp
|
||||
int y = 5;
|
||||
cout << y++ << endl; // 这里又会输出什么?
|
||||
cout << y << endl; // 这一行又输出什么?
|
||||
```
|
||||
**计算机的执行过程**:
|
||||
|
||||
1. 遇到 `y++`,这是一个后置自增。
|
||||
2. **第一步 (先用)**:使用 `y` **原始的值 `5`** 来执行 `cout` 输出。所以第一行会输出 `5`。
|
||||
3. **第二步 (再变)**:在第一行 `cout` 语句**执行完毕后**,`y` 的值从 `5` 变为 `6`。
|
||||
4. 执行第二行 `cout << y;` 时,`y` 的值已经是 `6` 了。
|
||||
5. **最终结果**:屏幕上第一行输出 `5`,第二行输出 `6`。
|
||||
|
||||
* **复合赋值运算符**
|
||||
还有一些方便的简写形式,它们将算术运算和赋值结合起来,以下的例子中 `a` 与 `b` 均为整型变量:
|
||||
|
||||
* `a += b;` 等价于 `a = a + b;`
|
||||
* `a -= b;` 等价于 `a = a - b;`
|
||||
* `a *= b;` 等价于 `a = a * b;`
|
||||
* `a /= b;` 等价于 `a = a / b;`
|
||||
* `a %= b;` 等价于 `a = a % b;`
|
||||
|
||||
---
|
||||
|
||||
### **第二部分:关系运算符**
|
||||
|
||||
* **问题引入**:假设你要编写一个程序,判断一个学生的分数是否及格(大于等于60分)。或者,在一个游戏中,判断玩家的生命值是否已经降到了0。这些“是否大于等于”、“是否等于”的操作,单纯用算术运算符是无法完成的。我们需要新的工具来让程序进行**比较**和**判断**。
|
||||
|
||||
* **价值阐述**:如果说算术运算符让程序有了计算能力,那么关系运算符则赋予了程序**决策能力**。它是构建所有复杂逻辑(如 `if` 语句、循环)的基础。没有关系运算,程序就只是一台高级计算器,无法根据不同的情况做出不同的反应。
|
||||
|
||||
* **学习目标**:
|
||||
1. 理解并掌握 `bool` (布尔) 类型,知道它只有 `true` 和 `false` 两个值。
|
||||
2. 熟练使用 C++ 的 6 个关系运算符:`==`, `!=`, `>`, `<`, `>=`, `<=`。
|
||||
3. 理解关系运算符的运算结果是一个 `bool` 值。
|
||||
4. 掌握算术运算符和关系运算符混合使用时的**优先级**规则。
|
||||
|
||||
#### 2. 核心思想
|
||||
|
||||
* **思路铺垫:认识一个新的数据类型 `bool` 类型**
|
||||
在学习比较之前,我们得先知道比较的结果是什么。生活中的比较,结果通常是“是”或“否”。
|
||||
|
||||
* “你的年龄大于18岁吗?” -> “是” 或 “否”
|
||||
* “今天下雨了吗?” -> “是” 或 “否”
|
||||
在 C++ 中,我们用一种专门的类型来存储这种“是/否”、“真/假”的值,它就是 `bool` (布尔) 类型。
|
||||
* `true` (真): 代表“是”、“成立”。在计算机内部,通常用 `1` 来表示。
|
||||
* `false` (假): 代表“否”、“不成立”。在计算机内部,通常用 `0` 来表示。
|
||||
|
||||
```cpp
|
||||
bool isAdult = true; // 定义了一个 bool 类型的变量 isAdult 的值是 true
|
||||
bool isRaining = false; // 定义了一个 bool 类型的变量 isRaining 的值是 false
|
||||
```
|
||||
|
||||
* **关系运算符的种类**
|
||||
关系运算符就是用来比较两个值,其实很多关系与数学上是相同的。
|
||||
|
||||
| 运算符 | 名称 | 含义 | 例子 (a=5, b=10) | 结果 |
|
||||
| :----- | :------- | :------------------------- | :--------------- | :------ |
|
||||
| `==` | 等于 | 判断两边的值**是否相等** | `a == 5` | `true` |
|
||||
| `!=` | 不等于 | 判断两边的值是否不相等 | `a != b` | `true` |
|
||||
| `>` | 大于 | 判断左边的值是否大于右边 | `a > b` | `false` |
|
||||
| `<` | 小于 | 判断左边的值是否小于右边 | `a < b` | `true` |
|
||||
| `>=` | 大于等于 | 判断左值是否大于或等于右值 | `a >= 5` | `true` |
|
||||
| `<=` | 小于等于 | 判断左值是否小于或等于右值 | `b <= a` | `false` |
|
||||
|
||||
* **运算符优先级**
|
||||
当一个表达式里既有算术运算符又有关系运算符时,谁先算?比如 `3 + 4 > 2 * 3`。
|
||||
规则很简单:**先算术,后关系**。
|
||||
1. **最高级**:括号 `()`,永远最先计算。
|
||||
2. **第二级**:乘、除、取余 `*`, `/`, `%`。
|
||||
3. **第三级**:加、减 `+`, `-`。
|
||||
4. **第四级**:大小关系 `>`, `<`, `>=`, `<=`。
|
||||
5. **第五级**:相等关系 `==`, `!=`。
|
||||
|
||||
#### 3. 实例
|
||||
|
||||
* **具体案例**:分析表达式 `3 + 4 > 2 * 3` 的计算过程。
|
||||
|
||||
* **分步**:
|
||||
1. **扫描表达式**:`3 + 4 > 2 * 3`
|
||||
2. **应用优先级规则**:`*` 的优先级高于 `+` 和 `>`。
|
||||
* **计算 `2 * 3`**,得到 `6`。表达式变为 `3 + 4 > 6`。
|
||||
3. **再次扫描表达式**:`3 + 4 > 6`
|
||||
4. **应用优先级规则**:`+` 的优先级高于 `>`。
|
||||
* **计算 `3 + 4`**,得到 `7`。表达式变为 `7 > 6`。
|
||||
5. **最后一步**:执行关系运算 `7 > 6`。这个比较是成立的,所以结果是 `true`。
|
||||
|
||||
* 而在 `cout` 中直接输出 `bool` 值时,`true` 会显示为 `1`,`false` 会显示为 `0`。所以 `cout << (3 + 4 > 2 * 3);` 会输出 `1`。
|
||||
|
||||
#### 4. 代码实现
|
||||
|
||||
* **问题**:(书本 P33 例 3-1) 输入两个整数 `a` 和 `b`,判断并输出:
|
||||
1. `a` 是否大于 `b`?
|
||||
2. `a` 是否小于或等于 `b`?
|
||||
3. `a` 是否不等于 `b`?
|
||||
输出 3 个整数(1 代表真,0 代表假),用空格隔开。
|
||||
|
||||
* **完整代码**:
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
// 定义需要输入的两个整型变量
|
||||
int a, b;
|
||||
|
||||
// 从键盘读取 a 和 b 的值
|
||||
cin >> a >> b;
|
||||
|
||||
// 计算第一个关系表达式 (a > b) 的结果并输出, a > b 的结果是一个 bool 值 (true 或 false)
|
||||
// cout 会自动将 true 转为 1, false 转为 0
|
||||
cout << (a > b) << " ";
|
||||
|
||||
// 计算第二个关系表达式 (a <= b) 的结果并输出
|
||||
cout << (a <= b) << " ";
|
||||
|
||||
// 计算第三个关系表达式 (a != b) 的结果并输出
|
||||
cout << (a != b) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
* **代码解读**:
|
||||
* `cin >> a >> b;`: 等待用户输入两个整数,分别存入变量 `a` 和 `b`。
|
||||
* `cout << (a > b) << " ";`: 这一行是核心。
|
||||
* ` (a > b)`: 括号不是必须的,但加上能让代码更清晰。计算机会先执行括号里的 `a > b`。
|
||||
* 假如输入 `10 5`,则 `10 > 5` 结果为 `true`。
|
||||
* `cout << true;`: `cout` 会将 `true` 以整数 `1` 的形式打印到屏幕上。
|
||||
* `<< " ";`: 紧接着输出一个空格,用于分隔结果。
|
||||
* 其他两行 `cout` 的逻辑完全相同。
|
||||
|
||||
#### 5. 验证与深化
|
||||
|
||||
* **常见问题 **
|
||||
1. **最大的陷阱:`==` 和 `=` 的区别是什么?**
|
||||
* `==` (两个等号) 是**关系运算符**,用来**判断**左右两边是否相等。它返回一个 `bool` 值。例如 `if (a == 5)` 是在问“a 等于 5 吗?”。
|
||||
* `=` (一个等号) 是**赋值运算符**,用来把右边的值**赋给**左边的变量。例如 `a = 5;` 是在命令“让 a 的值变成 5”。
|
||||
* **最常犯的错误**就是在需要判断的地方写了赋值,例如 ` a = 5`,这会导致逻辑错误且很难发现!**请务必牢记!**
|
||||
|
||||
2. **`y++` 所在的这行代码结束后,`y` 的值到底变了没有?**
|
||||
* **绝对变了!** 后置运算符的“后”指的是在“使用”之后,但在整个语句结束之前,变量的值就已经更新了。只要记住口诀“先用旧值,再变新值”就不会错。
|
||||
|
||||
3. **任何数字都能转成 `bool` 类型吗?**
|
||||
* 是的。C++ 有一个规则:**非零即为真**。
|
||||
* 当一个整数或浮点数转换为 `bool` 类型时,只要它的值**不是 `0`**,就转为 `true`。只有 `0` 会转为 `false`。
|
||||
* 例如:`(bool) -3` 的结果是 `true`,`(bool) 100` 的结果是 `true`,而 `(bool) 0` 的结果是 `false`。
|
||||
|
||||
---
|
||||
|
||||
#### 6. 总结与练习
|
||||
|
||||
* **要点回顾**
|
||||
1. **算术运算符**:`+`, `-`, `*`, `/` (整除), `%` (取余)。
|
||||
2. **自增/自减**:`++` 和 `--` 是 `+1` 和 `-1` 的简写。
|
||||
3. **前置 vs 后置**:`++a` (先变后用),`a++` (先用后变)。
|
||||
4. **`bool` 类型**:专门存储 `true` (1) 和 `false` (0) 的类型,是判断的基础。
|
||||
5. **关系运算符**:`==`, `!=`, `>`, `<`, `>=`, `<=`,它们的结果都是 `bool` 类型。
|
||||
6. **优先级**:先算术,后关系。括号优先级最高。
|
||||
* **拓展思考**
|
||||
我们已经学会了如何进行一次比较,比如 `a > b`。但如果我想判断“一个数 `x` 是否既大于 0 又小于 10”呢?这需要**两个**关系运算同时成立。要连接多个关系表达式,我们就需要学习下一讲的内容——**逻辑运算符** (`&&`, `||`, `!`)。它们是构建更复杂判断逻辑的桥梁。
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,158 @@
|
||||
# 逻辑运算符
|
||||
|
||||
### 1. 引言
|
||||
|
||||
* **问题引入**:
|
||||
妈妈许诺说:“如果你这次数学考到90分,**并且**英语也考到90分,我就给你买新的游戏机!”
|
||||
这里的关键是“**并且**”,它意味着两个条件必须**同时**满足。
|
||||
后来妈妈看你压力太大了,又说:好吧,要求降低一点。只要你数学考到90分,**或者**英语考到90分,我就带你去吃大餐!
|
||||
这里的关键是“**或者**”,它意味着两个条件只要满足**任意一个**就行。
|
||||
在C++中,我们如何表达这种“并且”、“或者”的复杂逻辑呢?
|
||||
|
||||
* **价值阐述**:逻辑运算符是构建程序决策的核心。它让我们可以将简单的判断 (`a > b`, `c == 0`) 组合成复杂的逻辑规则。从网站的用户登录(用户名**和**密码都正确)、游戏胜利条件(敌人数量为0**或**到达终点)、到复杂的AI决策,逻辑运算符无处不在。
|
||||
|
||||
* **学习目标**:
|
||||
1. 掌握 C++ 的三个逻辑运算符:`&&` (与), `||` (或), `!` (非)。
|
||||
2. 理解并能口述每个运算符的运算规则。
|
||||
3. 掌握“短路求值”这一重要特性,并理解其意义。
|
||||
4. 了解逻辑运算符、关系运算符和算术运算符之间的优先级关系。
|
||||
|
||||
### 2. 核心思想
|
||||
|
||||
* **思路铺垫**:
|
||||
我们已经知道,关系运算符(如 `>`、`==`)的运算结果是一个 `bool` 值(`true` 或 `false`)。逻辑运算符不做数值计算,它的工作对象就是这些 `bool` 值。它根据输入的 `true` 或 `false`,给出一个最终的 `true` 或 `false` 结果。
|
||||
|
||||
* **算法精讲**:
|
||||
C++ 主要有三个逻辑运算符,我们用来一一拆解。
|
||||
1. **逻辑与 `&&` (AND)**
|
||||
* **含义**:表示“并且”,要求左右两边的条件**都**为 `true` 时,最终结果才是 `true`。只要有一个是 `false`,结果就是 `false`。
|
||||
* **生活实例**:`数学 >= 90 && 英语 >= 90`。
|
||||
* **规则表 (真值表)**:
|
||||
| A | B | A && B |
|
||||
| :---: | :---: | :----: |
|
||||
| `true` | `true` | `true` |
|
||||
| `true` | `false`| `false`|
|
||||
| `false`| `true` | `false`|
|
||||
| `false`| `false`| `false`|
|
||||
* **记忆口诀**:**全真才为真,一假即为假。**
|
||||
|
||||
2. **逻辑或 `||` (OR)**
|
||||
含义**:表示“或者”,只要左右两边的条件有**任意一个**为 `true`,最终结果就是 `true`。只有当两个都为 `false` 时,结果才是 `false`。
|
||||
生活实例**:`数学 >= 90 || 英语 >= 90`。
|
||||
**规则表 (真值表)**:
|
||||
| A | B | A \|\| B |
|
||||
| :---: | :---: | :----: |
|
||||
| `true` | `true` | `true` |
|
||||
| `true` | `false`| `true` |
|
||||
| `false`| `true` | `true` |
|
||||
| `false`| `false`| `false`|
|
||||
* **记忆口诀**:**一真即为真,全假才为假。**
|
||||
|
||||
3. **逻辑非 `!` (NOT)**
|
||||
|
||||
**含义**:表示“取反”,它是一个单目运算符(只有一个操作数)。它会把 `true` 变成 `false`,把 `false` 变成 `true`。
|
||||
|
||||
**生活实例**:妈妈说:“只要你数学**不**低于70分就有奖励”。“不低于70分”等价于 `!(数学 < 70)`。
|
||||
|
||||
**规则表 (真值表)**:
|
||||
| A | !A |
|
||||
| :---: | :----: |
|
||||
| `true` | `false`|
|
||||
| `false`| `true` |
|
||||
* **记忆口诀**:**真变假,假变真。**
|
||||
|
||||
* **步骤拆解 (特性:短路求值)**
|
||||
计算机其实很聪明,它会用最快的方式得到逻辑运算的结果。
|
||||
|
||||
* **对于 `&&` (与)**:`条件A && 条件B`
|
||||
1. 计算机先计算 `条件A`。
|
||||
2. 如果 `条件A` 的结果是 `false`,它会想:“根据‘一假即为假’的规则,无论 `条件B` 是什么,最终结果肯定是 `false` 了。”
|
||||
3. 于是,计算机**直接返回 `false`,根本不会去计算 `条件B`**。这个行为就叫“短路”。
|
||||
* **回到例子**:如果你的数学考了88分 (`math >= 90` 为 `false`),计算机根本不需要再看你的英语成绩,就知道你拿不到游戏机了。
|
||||
|
||||
* **对于 `||` (或)**:`条件A || 条件B`
|
||||
|
||||
1. 计算机先计算 `条件A`。
|
||||
2. 如果 `条件A` 的结果是 `true`,它会想:“根据‘一真即为真’的规则,无论 `条件B` 是什么,最终结果肯定是 `true` 了。”
|
||||
3. 于是,计算机**直接返回 `true`,根本不会去计算 `条件B`**。
|
||||
* **回到例子**:如果你的数学考了100分 (`math >= 90` 为 `true`),计算机根本不需要再看你的英语成绩,就知道你已经有大餐吃了。
|
||||
|
||||
### 3. 实例
|
||||
|
||||
* **具体案例**:
|
||||
假设 `int score = 85;`,我们来分析表达式 `score > 80 && score < 90` 的真假。
|
||||
* **分步演示**:
|
||||
1. **拆分表达式**:这个逻辑表达式由两个关系表达式 `score > 80` 和 `score < 90`,以及一个逻辑运算符 `&&` 组成。
|
||||
2. **计算左侧**:`score > 80` -> `85 > 80` -> 结果为 `true`。
|
||||
3. **判断短路**:因为是 `&&` 运算,左侧为 `true` 还不能确定最终结果,所以**不能短路**,必须继续计算右侧。
|
||||
4. **计算右侧**:`score < 90` -> `85 < 90` -> 结果为 `true`。
|
||||
5. **最终结果**:`true && true` -> 根据 `&&` 的规则,最终结果为 `true`。
|
||||
|
||||
### 4. 代码实现
|
||||
|
||||
* **问题**:输入一个学生的数学和英语成绩,判断他是否能拿到游戏机(两门都>=90),是否能吃到大餐(任意一门>=90)。
|
||||
|
||||
* **完整代码**:
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int math_score, english_score;
|
||||
cout << "请输入数学成绩和英语成绩: ";
|
||||
cin >> math_score >> english_score;
|
||||
|
||||
// 判断是否能拿到游戏机 (&&)
|
||||
bool can_get_game = (math_score >= 90) && (english_score >= 90);
|
||||
|
||||
// 判断是否能吃到大餐 (||)
|
||||
bool can_get_dinner = (math_score >= 90) || (english_score >= 90);
|
||||
|
||||
// (了解即可)C++中,boolalpha 可以让我们直接输出 true 或 false 而不是被计算机转化的 0 和 1
|
||||
// 如果不添加下面这一行 cout << boolalpha; 那么输出 true 或 false 就会被计算机转为 1 和 0
|
||||
cout << boolalpha;
|
||||
|
||||
cout << "能拿到游戏机吗? " << can_get_game << endl;
|
||||
cout << "能吃到大餐吗? " << can_get_dinner << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
* **代码解读**:
|
||||
* `bool can_get_game = (math_score >= 90) && (english_score >= 90);`
|
||||
* 我们把整个逻辑表达式的结果存入一个 `bool` 类型的变量 `can_get_game`。
|
||||
* 括号 `()` 的使用让代码的可读性变得非常好,我们一眼就能看出是在对两个条件进行 `&&` 操作。
|
||||
* `cout << boolalpha;`
|
||||
* 这是一个输出格式控制器。加上它之后,`cout` 在打印 `bool` 值时,会打印出 "true" 或 "false" ,而不是 "1" 或 "0",这样结果更直观。
|
||||
|
||||
### 5. 深化
|
||||
* **运算符优先级**
|
||||
当一个复杂的表达式里什么运算符都有的时候,计算顺序是怎样的?
|
||||
**口诀:==非算关与或==** (`非` > `算术` > `关系` > `与` > `或`)
|
||||
|
||||
1. **最高**:`!` (逻辑非) 和 `()` (括号)
|
||||
2. **次高**:算术运算符 (`*`, `/`, `+`, `-`)
|
||||
3. **中等**:关系运算符 (`>`, `<`, `==`, `!=`)
|
||||
4. **次低**:`&&` (逻辑与)
|
||||
5. **最低**:`||` (逻辑或)
|
||||
|
||||
**黄金法则**:如果你不确定优先级,或者想让代码意图更清晰,**那就毫不犹豫地使用括号 `()`**!例如 `(a + b > 5) && (c == 0)`。
|
||||
|
||||
* **常见问题**:
|
||||
|
||||
1. **`0 || 0` 的结果是什么?**
|
||||
* 我们知道“非零即为真”,所以 `0` 在逻辑判断中被当作 `false`。
|
||||
* 表达式相当于 `false || false`。根据 `||` 的“全假才为假”规则,结果为 `false` (会输出 0)。
|
||||
2. `!(-3)` 的结果是什么?
|
||||
* `-3` 是一个非零数,所以它被当作 `true`。
|
||||
* 表达式相当于 `!(true)`。根据 `!` 的取反规则,结果为 `false` (会输出 0)。
|
||||
|
||||
### 6. 总结
|
||||
|
||||
* **要点回顾**:
|
||||
1. **逻辑与 `&&`**:全真才为真。左侧为假时发生短路。
|
||||
2. **逻辑或 `||`**:一真即为真。左侧为真时发生短路。
|
||||
3. **逻辑非 `!`**:取反,真变假,假变真。
|
||||
4. **优先级**:`!` > 算术 > 关系 > `&&` > `||`。**括号是王道**,**口诀:非算关与或**。
|
||||
5. **短路求值**:一种优化策略,可以避免不必要的计算。
|
||||
Binary file not shown.
+99
@@ -0,0 +1,99 @@
|
||||
### **C++ 逻辑表达式的构建 讲义**
|
||||
|
||||
#### **一、 目标**
|
||||
|
||||
我们的目标,是将生活中的复杂规则(自然语言)准确地翻译成计算机能懂的、没有歧义的逻辑表达式(代码)。
|
||||
|
||||
#### **二、 翻译的步骤公式**
|
||||
|
||||
无论规则多复杂,都可以遵循这三步:
|
||||
|
||||
1. **拆解**:将一句长长的规则,拆分成一个个最小的、不可再分的**独立判断条件**。
|
||||
* 例:“一个数字 `x` 是大于4的偶数” -> 拆成 `x > 4` 和 `x是偶数`。
|
||||
|
||||
2. **观察连接词**:找出连接这些独立条件的**逻辑关系词**。
|
||||
* “并且”、“同时”、“但” -> 对应 C++ 的 `&&`。**全真才为真,一假即为假。**
|
||||
* “或者”、“至少一个” -> 对应 C++ 的 `||`。**一真即为真,全假才为假。**
|
||||
* “不”、“不是” -> 对应 C++ 的 `!`,将一个条件的结果**取反**。
|
||||
|
||||
3. **组合**:用 C++ 的逻辑运算符将这些条件按顺序组合起来。
|
||||
|
||||
#### **三、 优先级**
|
||||
|
||||
计算机在计算表达式时,并不是简单地从左到右。也就是存在**运算符优先级**。**记忆口诀:非算关与或**
|
||||
|
||||
* **基本规则**:`!` (逻辑非) 的优先级最高,其次是 `&&` (逻辑与),最后是 `||` (逻辑或)。
|
||||
* **使用括号 `()` 明确意图**
|
||||
* 为了避免优先级带来的混淆和错误,当一个表达式中同时包含多个逻辑运算符的时候时,**使用括号 `()` 来明确你的逻辑分组**,这既能保证程序正确,也让代码更容易阅读。
|
||||
* 例如:如果你数学**或者**英语考了100分,**并且**作业都写完了,我们就去游乐园。
|
||||
* 错误写法: `数学100分 || 英语100分 && 作业都写完了`(错误原因: `&&` 的优先级比 `||` 高)
|
||||
* 正确写法: `(数学100分 || 英语100分) && 作业都写完了`。
|
||||
|
||||
#### **四、 布尔变量**
|
||||
|
||||
以后当我们写条件表达式的时候,如果一个判断条件的结果,已经被保存在一个布尔(bool)变量里了,我们就可以直接根据它的语义来去使用。
|
||||
|
||||
假设我们已经将两个判断条件,分别存入了布尔变量 `a` 和 `b` 中:
|
||||
* `bool a = (考试成绩 > 80);` // a 代表“考试成绩大于80分”这件事
|
||||
* `bool b = (综合成绩 > 90);` // b 代表“综合成绩大于90分”这件事
|
||||
|
||||
当我需要写一个条件表达式来判断:“考试成绩大于80分 **并且** 综合成绩大于90分”时,我们就可以像翻译句子一样,把自然语言和我们的代码进行一一对照:
|
||||
|
||||
* “考试成绩大于80分” → 这正是我们的布尔变量 `a` 所代表的含义。
|
||||
* “并且” → 在代码中对应的就是逻辑运算符 `&&`。
|
||||
* “综合成绩大于90分” → 这正是我们的布尔变量 `b` 所代表的含义。
|
||||
|
||||
然后,把它们按顺序串联起来,就得到了最终的表达式:`a && b`。
|
||||
|
||||
这种方式让我们的代码逻辑和自然语言逻辑完全对应。而不需要通过 `a == true && b == true` 重复进行判断。
|
||||
|
||||
#### **五、 整除的逻辑表达式**
|
||||
|
||||
在编程中,我们经常需要判断一个数能否被另一个数整除。这在判断奇偶性、倍数关系时非常有用。
|
||||
|
||||
* **工具**:求余运算符 `%`。`a % b` 的意思是计算 `a` 除以 `b` 之后的**余数**。
|
||||
* **逻辑**:如果 `a` 能被 `b` 整除,那么 `a` 除以 `b` 之后**没有余数**,所以 **`a % b` 的结果就是 `0`**。
|
||||
* **实例**:
|
||||
* `9 % 3` 的结果是 `0`,所以 `9 % 3 == 0` 为 `true`,代表9是3的倍数。
|
||||
* `10 % 3` 的结果是 `1`,所以 `10 % 3 == 0` 为 `false`,代表10不能被3整除。
|
||||
|
||||
#### **六、 构建实例**
|
||||
|
||||
##### **实例1:闰年判断**
|
||||
|
||||
* **规则**:年份能被4整除**但**不能被100整除,**或者**能被400整除。
|
||||
* **第一步:拆解**
|
||||
* 条件A: 年份能被4整除 -> `year % 4 == 0`
|
||||
* 条件B: 年份不能被100整除 -> `year % 100 != 0`
|
||||
* 条件C: 年份能被400整除 -> `year % 400 == 0`
|
||||
* **第二步:观察连接词**
|
||||
|
||||
* 条件A和B之间是“但”(也就是“并且”)的关系。
|
||||
* (A和B的整体) 与 条件C之间是“或者”的关系。
|
||||
* **第三步:组合(使用括号明确优先级)**
|
||||
|
||||
```cpp
|
||||
bool a = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
|
||||
```
|
||||
|
||||
##### **实例2:数字性质筛选**
|
||||
|
||||
* **规则**:一个数字 `x` 要满足“是3的倍数,但不是偶数”。
|
||||
* **第一步:拆解,并用布尔变量存起来**
|
||||
|
||||
* 条件A:“是3的倍数”
|
||||
```cpp
|
||||
bool b = (x % 3 == 0); // "是3的倍数" 的结果存在布尔变量 b 里
|
||||
```
|
||||
* 条件B:“是偶数”
|
||||
```cpp
|
||||
bool c = (x % 2 == 0); // "是偶数" 的结果存在布尔变量 c 里
|
||||
```
|
||||
* **第二步:观察连接词**
|
||||
* 条件A 和 “不是条件B” 之间是“但”(“并且”)的关系。
|
||||
* **第三步:组合(使用布尔变量)**
|
||||
|
||||
```cpp
|
||||
// 条件A和条件B的结果已经储存在布尔变量中了,可直接根据语义去使用。
|
||||
bool d = b && !c;
|
||||
```
|
||||
BIN
Binary file not shown.
+37
@@ -0,0 +1,37 @@
|
||||
### **C++ 算术与关系运算符 课后习题 - 答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `/` , `%`
|
||||
2. `bool`
|
||||
3. 先变,再用
|
||||
4. 先用,再变
|
||||
5. `score = score - 10;`
|
||||
6. 乘法 (`*`) , 加法 (`+`) , 关系 (`>`)
|
||||
7. `==` , `=`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **C**. 整数除法舍弃小数,`13 / 5` 的商是 `2`。
|
||||
2. **A**. `13` 除以 `5` 商 `2` 余 `3`。
|
||||
3. **B**. 前置自增,先将 `x` 变为 `11`,再输出新值 `11`。
|
||||
4. **A**. 后置自增,先输出 `x` 的原值 `10`,然后 `x` 的值才变为 `11`。
|
||||
5. **C**. 前置自减,`x` 先从 `5` 变为 `4`,然后将新值 `4` 赋给 `y`。
|
||||
6. **C**. 后置自减,先将 `x` 的原值 `5` 赋给 `y`,然后 `x` 自身的值从 `5` 变为 `4`。
|
||||
7. **C**. 先算术后关系。`5 + 2` 得 `7`,`8 - 4` 得 `4`。表达式变为 `7 > 4`,结果为 `true`,输出 `1`。
|
||||
8. **B**. `score /= 10;` 等价于 `score = score / 10;`,即 `100 / 10`,结果是 `10`。
|
||||
9. **C**. 不等于的关系运算符是 `!=`。
|
||||
10. **B**. `a++` 是后置自增,先用 `a` 的原值 `1` 参与运算,`1 + 2` 结果为 `3`。运算结束后,`a` 的值变为 `2`。
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √ (两个整数相除,结果只取整数部分。)
|
||||
2. √ (当不把它们作为表达式的一部分,而是独立作为一条语句时,两者都只是让变量自增1,效果相同。)
|
||||
3. × (根据讲义内容,`%` 主要用于整数运算。)
|
||||
4. × ( `==` 是判断相等,返回 `bool` 值; `=` 是赋值,改变变量的值。)
|
||||
5. × (这是后置 `++`,遵循“先用后变”原则,应是先把 `x` 的旧值赋给 `y`,然后 `x` 再加1。)
|
||||
6. √ (这是 `cout` 对于 `bool` 类型的默认输出规则。)
|
||||
7. √ (`10 >= 20` 这个关系不成立,结果是 `false`,输出为 `0`。)
|
||||
8. √ (讲义中明确指出“非零即为真”。)
|
||||
9. √ (括号用于强制改变运算优先级,是最高的。)
|
||||
10. √ ( `b = a++` 是后置运算,先将 `a` 的原值 `10` 赋给 `b`,然后 `a` 自身的值变为 `11`。 )
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
### **C++ 算术与关系运算符 课后习题**
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 两个整数相除,只会保留整数部分而舍弃小数的运算符是 \_\_\_\_\_\_\_\_\_\_;而计算整数除法余数的运算符是 \_\_\_\_\_\_\_\_\_\_。
|
||||
2. 在C++中,专门用来存储 `true` (真) 和 `false` (假) 这种值的类型是 \_\_\_\_\_\_\_\_\_\_ 类型。
|
||||
3. 前置自增 `++a` 的运算口诀是“\_\_\_\_\_\_\_\_\_\_,\_\_\_\_\_\_\_\_\_\_”,即先改变变量的值,再使用新值参与表达式运算。
|
||||
4. 后置自增 `a++` 的运算口诀是“\_\_\_\_\_\_\_\_\_\_,\_\_\_\_\_\_\_\_\_\_”,即先使用变量的旧值参与表达式运算,再改变变量的值。
|
||||
5. `score -= 10;` 这种写法叫做复合赋值,它和普通写法 \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ 是等价的。
|
||||
6. 在 `3 + 4 > 2 * 3` 这个表达式中,计算机会先计算 \_\_\_\_\_\_\_\_\_\_ 运算,再计算 \_\_\_\_\_\_\_\_\_\_ 运算,最后才进行 \_\_\_\_\_\_\_\_\_\_ 运算。
|
||||
7. 请务必区分:用于**判断**两个值是否相等的运算符是 \_\_\_\_\_\_\_\_\_\_,而用于**赋值**的运算符是 \_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 执行 `int a = 13, b = 5; cout << a / b;` 后,屏幕上会显示什么?
|
||||
A. 3   B. 2.6   C. 2   D. 8
|
||||
|
||||
( ) 2. 执行 `int a = 13, b = 5; cout << a % b;` 后,屏幕上会显示什么?
|
||||
A. 3   B. 2.6   C. 2   D. 0
|
||||
|
||||
( ) 3. 阅读以下代码,其输出结果是什么?
|
||||
```cpp
|
||||
int x = 10;
|
||||
cout << ++x;
|
||||
```
|
||||
A. 10   B. 11   C. 9   D. 无法确定
|
||||
|
||||
( ) 4. 阅读以下代码,其输出结果是什么?
|
||||
```cpp
|
||||
int x = 10;
|
||||
cout << x++;
|
||||
```
|
||||
A. 10   B. 11   C. 9   D. 无法确定
|
||||
|
||||
( ) 5. 阅读以下代码,执行后 `y` 的值是多少?
|
||||
```cpp
|
||||
int x = 5;
|
||||
int y = --x;
|
||||
```
|
||||
A. 5   B. 6   C. 4   D. 3
|
||||
|
||||
( ) 6. 阅读以下代码,执行完毕后 `x` 的值是多少?
|
||||
```cpp
|
||||
int x = 5;
|
||||
int y = x--;
|
||||
```
|
||||
A. 5   B. 6   C. 4   D. 3
|
||||
|
||||
( ) 7. `cout << (5 + 2 > 8 - 4);` 这行代码的输出结果是?
|
||||
A. true   B. false   C. 1   D. 0
|
||||
|
||||
( ) 8. `int score = 100; score /= 10;` 执行后,变量 `score` 的值是多少?
|
||||
A. 100   B. 10   C. 90   D. 110
|
||||
|
||||
( ) 9. “判断变量 `a` 的值是否不等于 `b`”,应该使用哪个表达式?
|
||||
A. `a =! b`   B. `a <> b`   C. `a != b`   D. `a = b`
|
||||
|
||||
( ) 10. `int a = 1, b = 2; cout << (a++ + b);` 这行代码的输出结果是?
|
||||
A. 2   B. 3   C. 4   D. 5
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
1. `10 / 4` 在C++整型计算中的结果是 `2`。 ( )
|
||||
|
||||
2. `a++` 和 `++a` 作为独立的一行语句时,例如 `a++;` 和 `++a;`,它们的效果是完全一样的。 ( )
|
||||
|
||||
3. 取余(取模)运算符 `%` 可以用于 `double` 类型的变量。 ( )
|
||||
|
||||
4. 在C++中,关系运算符 `==` 和赋值运算符 `=` 的作用是相同的。 ( )
|
||||
|
||||
5. 在表达式 `int y = x++;` 中,是先把 `x` 的值加1,然后再把新值赋给 `y`。 ( )
|
||||
|
||||
6. 当 `cout` 一个 `bool` 类型的值时,`true` 会显示为 `1`,`false` 会显示为 `0`。 ( )
|
||||
|
||||
7. 以下代码执行后,会输出 `0`。 ( )
|
||||
```cpp
|
||||
int a = 10, b = 20;
|
||||
cout << (a >= b);
|
||||
```
|
||||
|
||||
8. 在C++中,只要一个数值不是 `0`,当它被用在逻辑判断中时,就会被当作 `true`。 ( )
|
||||
|
||||
9. 运算符 `()` 的优先级在所有运算符中是最高的。 ( )
|
||||
|
||||
10. 以下代码执行完毕后,变量 `a` 的最终值是 `11`。 ( )
|
||||
```cpp
|
||||
int a = 10;
|
||||
int b = a++;
|
||||
```
|
||||
BIN
Binary file not shown.
+37
@@ -0,0 +1,37 @@
|
||||
### **C++ 逻辑运算符 课后习题 - 答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `&&` , `||` , `!`
|
||||
2. 全真才为真
|
||||
3. 一真即为真
|
||||
4. `false` , `true`
|
||||
5. 短路求值 (或 短路)
|
||||
6. `!` (非) , `&&` (与) , `||` (或)
|
||||
7. 算 关 与
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **D**. `(5 > 3)` 为 `true`,`(2 < 1)` 为 `false`。`true && false` 的结果是 `false`,输出为 `0`。
|
||||
2. **A**. `(10 == 9)` 为 `false`,`(3 != 4)` 为 `true`。`false || true` 的结果是 `true`,输出为 `1`。
|
||||
3. **B**. `-1` 是非零数,被视为 `true`。`!true` 的结果是 `false`,即 `0`。
|
||||
4. **C**. 题干描述了两个并列的条件,应该用 `||` 连接。“能被4整除但不能被100整除”是 `year % 4 == 0 && year % 100 != 0`,“能被400整除”是 `year % 400 == 0`。
|
||||
5. **B**. `a` 是 `1` (true),`b` 是 `0` (false)。`true || false` 的结果是 `true`,输出为 `1`。
|
||||
6. **A**. 因为 `x > 1` (即 `5 > 1`) 的结果是 `true`,根据 `||` 的短路规则,后面的 `(y++ > 10)` 不会再执行,所以 `y` 的值保持 `10` 不变。
|
||||
7. **A**. 因为 `x > 1` (即 `0 > 1`) 的结果是 `false`,根据 `&&` 的短路规则,后面的 `(y++ > 10)` 不会再执行,所以 `y` 的值保持 `10` 不变。
|
||||
8. **D**. 一个数要么大于等于20,要么小于20,这两个条件覆盖了所有情况,所以用 `||` 连接起来结果永远为 `true`。
|
||||
9. **B**. `!` 优先级最高,`!true` 变为 `false`。表达式变为 `false || false && true`。`&&` 优先级高于 `||`,先算 `false && true` 结果为 `false`。最后表达式变为 `false || false`,结果为 `false`,即 `0`。
|
||||
10. **D**. `a > 1` (true) `&&` `a < 10` (false),`true && false` 结果为 `false`。其他选项结果都为 `true`。
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √ ( `&&` 的优先级高于 `||`,就像乘法高于加法一样。)
|
||||
2. √ (当 `a` 为0时,`!a` 为 `true`,`a == 0` 也为 `true`。当 `a` 非0时,`!a` 为 `false`,`a == 0` 也为 `false`。)
|
||||
3. × (它会先算 `5 < x`,结果是 `true`(1) 或 `false`(0),然后再拿这个 `1` 或 `0` 去和 `10` 比较,永远为 `true`。正确的写法是 `x > 5 && x < 10`。)
|
||||
4. × (关系运算符的优先级高于逻辑运算符。先判断大小关系,再进行逻辑组合。)
|
||||
5. × (这是 `||` 的短路特性,只要 `A` 为 `true`,整个表达式就确定为 `true`,无需再计算 `B`。)
|
||||
6. √ (`a > b` 即 `1 > 2` 为 `false`。`c > b` 即 `3 > 2` 为 `true`。`false || true` 结果为 `true`,输出 `1`。)
|
||||
7. × (`a` 是 `0`,即 `false`。对于 `&&` 运算,因为短路,`b++` 不会执行,`b` 的值仍然是 `10`。)
|
||||
8. √ (`0` 被视为 `false`,`!false` 的结果是 `true`,即 `1`。)
|
||||
9. √ (`true && false` 的结果是 `false`,`cout` 输出 `bool` 类型的 `false` 时会显示 `0`。)
|
||||
10. √ (这正是逻辑或 `||` 的定义。)
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,81 @@
|
||||
### **C++ 逻辑运算符 课后习题**
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. C++ 中用来表示逻辑“与”的运算符是 \_\_\_\_\_\_\_\_\_\_,表示逻辑“或”的运算符是 \_\_\_\_\_\_\_\_\_\_,表示逻辑“非”的运算符是 \_\_\_\_\_\_\_\_\_\_。
|
||||
2. 逻辑与 `&&` 的运算规则是:两个条件必须都为 `true`,结果才为 `true`,这叫做“\_\_\_\_\_\_\_\_\_\_,一假即为假”。
|
||||
3. 逻辑或 `||` 的运算规则是:只要有一个条件为 `true`,结果就为 `true`,这叫做“\_\_\_\_\_\_\_\_\_\_,全假才为假”。
|
||||
4. 在C++的逻辑判断中,整数 `0` 会被当作 \_\_\_\_\_\_\_\_\_\_ 来看待,而任何非零的整数(如 `5`、`-10`)都会被当作 \_\_\_\_\_\_\_\_\_\_ 来看待。
|
||||
5. 在 `A && B` 这个表达式中,如果 `A` 的值为 `false`,程序就不会再去计算 `B` 的值,这种现象叫做 \_\_\_\_\_\_\_\_\_\_。
|
||||
6. 运算符的优先级决定了计算顺序,逻辑运算符的优先级从高到低是:\_\_\_\_\_\_\_\_\_\_ > \_\_\_\_\_\_\_\_\_\_ > \_\_\_\_\_\_\_\_\_\_。
|
||||
7. 运算符优先级顺序的口诀是:非 > \_\_\_\_\_\_ > \_\_\_\_\_\_ > \_\_\_\_\_\_ > 或。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 执行 `cout << ((5 > 3) && (2 < 1));` 这行代码,屏幕上会输出什么?
|
||||
A. true   B. false   C. 1   D. 0
|
||||
|
||||
( ) 2. 执行 `cout << ((10 == 9) || (3 != 4));` 这行代码,屏幕上会输出什么?
|
||||
A. 1   B. 0   C. true   D. false
|
||||
|
||||
( ) 3. 表达式 `!(-1)` 的计算结果是什么?
|
||||
A. 1   B. 0   C. -1   D. 语法错误
|
||||
|
||||
( ) 4. “年份 `year` 是闰年”的条件是“能被4整除但不能被100整除,或者能被400整除”。下列哪个表达式是正确的?
|
||||
A. `year % 4 == 0 && year % 100 != 0 && year % 400 == 0`
|
||||
B. `year % 4 == 0 || year % 100 != 0 && year % 400 == 0`
|
||||
C. `(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)`
|
||||
D. `year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)`
|
||||
|
||||
( ) 5. 阅读以下代码,其输出结果是什么?
|
||||
```cpp
|
||||
int a = 1, b = 0;
|
||||
cout << (a || b);
|
||||
```
|
||||
A. 0   B. 1   C. 2   D. a
|
||||
|
||||
( ) 6. 阅读以下代码,执行后变量 `y` 的值是多少?
|
||||
```cpp
|
||||
int x = 5, y = 10;
|
||||
bool result = (x > 1) || (y++ > 10);
|
||||
```
|
||||
A. 10   B. 11   C. 5   D. 1
|
||||
|
||||
( ) 7. 阅读以下代码,执行后变量 `y` 的值是多少?
|
||||
```cpp
|
||||
int x = 0, y = 10;
|
||||
bool result = (x > 1) && (y++ > 10);
|
||||
```
|
||||
A. 10   B. 11   C. 0   D. 1
|
||||
|
||||
( ) 8. 下列表达式中,结果一定是 `true` (或 `1`) 的是?(假设 `x` 为 `int` 类型变量)
|
||||
A. `x > 0 && x < 0`   B. `x > 100`   C. `!(x > 10)`   D. `x >= 20 || x < 20`
|
||||
|
||||
( ) 9. 根据运算符优先级,表达式 `!true || false && true` 的结果是?
|
||||
A. 1   B. 0   C. 无法计算   D. true
|
||||
|
||||
( ) 10. `int a = 10;`,下列哪个表达式的结果是 `false` (或 `0`) ?
|
||||
A. `a > 5`   B. `a > 5 || a < 1`   C. `! (a == 5)`   D. `a > 1 && a < 10`
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
1. 逻辑运算符 `&&` 的优先级比 `||` 要高。 ( )
|
||||
2. 对于 `int` 型变量 `a`,表达式 `!a` 和 `a == 0` 在逻辑判断上是等价的。 ( )
|
||||
3. 在 C++ 中,`5 < x < 10` 这个表达式可以正确地判断 `x` 是否在 5 和 10 之间。 ( )
|
||||
4. 关系运算符(如 `>`、`==`)的优先级要低于逻辑运算符(如 `&&`)。 ( )
|
||||
5. 在表达式 `A || B` 中,如果 `A` 的计算结果为 `true`,那么计算机就必须再计算 `B` 的值才能确定最终结果。 ( )
|
||||
6. 以下代码执行后,会输出 `1`。 ( )
|
||||
```cpp
|
||||
int a = 1, b = 2, c = 3;
|
||||
cout << (a > b || c > b);
|
||||
```
|
||||
7. 以下代码执行后,变量 `b` 的值会变成 `11`。 ( )
|
||||
```cpp
|
||||
int a = 0, b = 10;
|
||||
bool result = a && (b++);
|
||||
```
|
||||
8. 表达式 `!0` 的计算结果是 `1`。 ( )
|
||||
9. `cout << (true && false);` 的输出结果是 `0`。 ( )
|
||||
10. 当我们想表达“两个条件中至少有一个满足”时,应该使用 `||` 运算符。 ( )
|
||||
BIN
Binary file not shown.
+28
@@ -0,0 +1,28 @@
|
||||
### **参考答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `&&`, 括号 `()`
|
||||
2. `(x % 3 == 0) && (x % 2 != 0) && (x % 5 != 0)`
|
||||
3. `is_blue && price < 50`
|
||||
4. `(x >= 10 && x <= 20) || (x >= 30 && x <= 40)`
|
||||
5. `!is_ready`
|
||||
6. `((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)`
|
||||
7. `(A && B) || (A && C) || (B && C)`
|
||||
8. `false`
|
||||
9. `!(x == 10)`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **B**. "等级和红宝石"是一个整体,"VIP和蓝宝石"是另一个整体,两者是“或者”关系。
|
||||
2. **B**. 因为 `chinese > 90` (88 > 90) 是 `false`,导致 `(math > 90 && chinese > 90)` 整体为 `false`。
|
||||
3. **C**. 选项A, B, D描述的都是“可以举办活动”的条件。选项C描述的是“**不能**举办活动”的条件,所以是错误的。
|
||||
4. **A**. `!(true && false)` -> `!false` -> `true`。 `(false || !true)` -> `(false || false)` -> `false`。最终 `true || false` -> `true`。
|
||||
5. **C**. "数学或者英语100分"是一个整体条件,需要用括号括起来,再与“作业写完”进行`&&`运算。
|
||||
7. **D**. 因为 `x > 5` (5 > 5) 是 `false`,导致整个`&&`表达式为`false`。其他选项均为`true`。
|
||||
8. **B**. “不大于10”就是“小于等于10”的意思。
|
||||
|
||||
#### **三、 构建逻辑表达式**
|
||||
|
||||
1. `login_ok || token_ok`
|
||||
2. `!is_special && (is_vip || amount > 200)`
|
||||
@@ -0,0 +1,80 @@
|
||||
### **C++ 逻辑运算符构建实例 **
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 当一个判断条件里既有 `&&` 又有 `||` 时,计算机会先算 \_\_\_\_\_\_\_\_\_\_\_\_\_部分。如果我们想改变运算顺序,可以使用 \_\_\_\_\_\_\_\_\_\_\_\_\_改变运算优先级。
|
||||
|
||||
2. 一个数字 `x` 要满足“是3的倍数,但不是2的倍数,也不是5的倍数”,这个条件写成逻辑表达式为:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
3. 小明想买一个玩具,条件是:玩具是蓝色的(结果储存在布尔变量`is_blue`中),并且价格(`price`)低于50元。这个购买条件可以写成表达式:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
4. 判断一个数 `x` 是否在区间 `[10, 20]` 或者 `[30, 40]` (包括边界)内,表达式可以写成:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
5. 如果布尔变量 `is_ready` 代表“准备就绪”,那么判断“**未**准备就绪”的最简洁表达式是 \_\_\_\_\_\_\_\_\_\_,而不是 `is_ready == false`。
|
||||
|
||||
6. 闰年的判断条件是:年份(`year`)能被4整除但不能被100整除,**或者**能被400整除。这个完整的表达式为: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
7. 如果 `A`, `B`, `C` 三个条件中**至少有两个**成立,那么表达式就可以写成:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。(提示:AB成立,或者AC成立,或者BC成立)
|
||||
|
||||
8. 已知 `bool a = true, b = false;`,那么表达式 `a && b` 的结果是 \_\_\_\_\_\_\_\_ (填`true`或`false`)。
|
||||
|
||||
9. 要判断“x不等于10”,我们可以写成 `x != 10`,也可以用逻辑非运算符写成 \_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 某游戏进入隐藏关卡的条件是:玩家等级(`level`)大于50 **并且** 拥有“红宝石”(`has_red_gem`),**或者** 玩家是VIP(`is_vip`)**并且** 拥有“蓝宝石”(`has_blue_gem`)。下面哪个表达式是正确的?
|
||||
A. `level > 50 && (has_red_gem || is_vip) && has_blue_gem`
|
||||
B. `(level > 50 && has_red_gem) || (is_vip && has_blue_gem)`
|
||||
C. `level > 50 || (has_red_gem && is_vip) || has_blue_gem`
|
||||
D. `level > 50 && has_red_gem && is_vip && has_blue_gem`
|
||||
|
||||
( ) 2. 学校评选“优秀少先队员”的条件是:数学成绩(`math`)和语文成绩(`chinese`)都在90分以上,并且品德成绩(`conduct`)不能低于85分。小明的成绩是 `math=95, chinese=88, conduct=90`。判断小明是否符合条件的表达式 `(math > 90 && chinese > 90) && conduct >= 85` 的结果是?
|
||||
A. true (1) B. false (0)
|
||||
|
||||
( ) 3. 一个机器人活动需要满足以下所有条件:天气晴朗(`is_sunny`),温度(`temp`)在15到25度之间,并且风力(`wind`)小于3级。下面哪个表达式是**错误**的?
|
||||
A. `is_sunny && (temp >= 15 && temp <= 25) && wind < 3`
|
||||
B. `is_sunny && temp >= 15 && temp <= 25 && wind < 3`
|
||||
C. `!is_sunny || temp < 15 || temp > 25 || wind >= 3`
|
||||
D. `is_sunny && temp >= 15 && !(temp > 25) && wind < 3`
|
||||
|
||||
( ) 4. 给定 `bool a = true; bool b = false; bool c = true;`,表达式 `!(a && b) || (b || !c)` 的结果是?
|
||||
A. true (1) B. false (0)
|
||||
|
||||
( ) 5. 小红的妈妈说:“如果你数学**或者**英语考了100分,**并且**作业都写完了,我们周末就去游乐园。” 假设 `math_ok` 代表数学100分,`eng_ok` 代表英语100分,`hw_done` 代表作业写完。下面哪个表达式正确地表达了去游乐园的条件?
|
||||
A. `math_ok || eng_ok && hw_done`
|
||||
B. `math_ok && eng_ok || hw_done`
|
||||
C. `(math_ok || eng_ok) && hw_done`
|
||||
D. `math_ok && (eng_ok || hw_done)`
|
||||
|
||||
( ) 6. 已知 `int x = 5, y = 10;`,下面哪个表达式的值是 `false`?
|
||||
A. `x < 10 && y > 5`
|
||||
B. `x == 5 || y == 5`
|
||||
C. `!(x > y)`
|
||||
D. `x > 5 && y == 10`
|
||||
|
||||
( ) 7. 表达式 `!(x > 10)` 和下面哪个表达式是等价的?
|
||||
A. `x < 10`
|
||||
B. `x <= 10`
|
||||
C. `x != 10`
|
||||
D. `x > 10`
|
||||
|
||||
#### **三、 构建逻辑表达式**
|
||||
|
||||
根据以下描述,使用给定的变量名写出对应的 C++ 逻辑表达式。
|
||||
|
||||
1. 一个账号可以登录,需要满足以下条件之一:
|
||||
* (1) 用户名和密码正确(结果储存在 `login_ok` 的布尔变量中)。
|
||||
|
||||
* (2) 用户通过了手机验证(结果储存在 `token_ok` 的布尔变量中)。
|
||||
|
||||
|
||||
**写出表达式:** \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
2. 一个商品可以享受折扣,条件是:
|
||||
* 商品**不是**“特价商品” (`is_special` 为 `false`)
|
||||
* **并且** (顾客是VIP会员(`is_vip`) **或者** 消费金额(`amount`)大于200元)。
|
||||
* 提示:`is_special` 与 `is_vip` 都是布尔变量
|
||||
|
||||
**写出表达式:** \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,105 @@
|
||||
### **C++ `if` 条件分支 讲义**
|
||||
|
||||
#### **1. 引言 **
|
||||
|
||||
* **顺序结构的局限**
|
||||
|
||||
* 在之前的课程中,我们学习了 C++ 的:变量(我们的数据容器)、运算符(进行计算和比较的工具)以及输入输出。我们写的代码,就像一条的单行道,从 `main` 函数的第一行开始,按照顺序,一句话一句话地执行下去,直到终点。
|
||||
|
||||
|
||||
但是,现实世界要复杂许多。我们每天都要做无数个决定:
|
||||
|
||||
* **如果**我饿了,**就**去吃饭。
|
||||
|
||||
* **如果**考试分数大于等于90分,**就**是优秀;**否则如果**大于等于80分,**就是**良好...
|
||||
|
||||
* 我们之前所写的代码都遵循一种**顺序结构**。就像下图的流程一样,程序从起点出发,一条路走到黑,中间没有任何改变方向的机会。
|
||||
|
||||
`int k = 1;` -> `k += 10;` -> `k++;` -> `++k;` -> `k %= 10;` -> `k += 6;`
|
||||
|
||||
无论运行多少次,只要初始值不变,结果永远是固定的。这种结构对于简单的计算是足够的,但它无法应对任何需要随机应变的场景。
|
||||
|
||||
如果想让我们的程序变得“智能”,能够模拟现实世界的逻辑,能够根据不同的情况做出不同的反应,那么我们就必须教会它如何**做选择**。
|
||||
|
||||
* **问题引入:让程序学会思考**
|
||||
|
||||
要让程序变得有用,它必须能够响应变化。比如:
|
||||
* **网站登录**:**如果**用户输入的密码**等于**正确的密码,**就**跳转到主页;**否则**,就提示“密码错误”。
|
||||
* **游戏逻辑**:**如果**玩家的生命值**小于或等于**0,**就**显示“游戏结束”。
|
||||
* **自动售货机**:**如果**投入的金额**大于或等于**商品价格,**就**出货并找零。
|
||||
|
||||
这些场景的核心,都在于一个词——**如果 (if)**。
|
||||
|
||||
---
|
||||
|
||||
#### **2. 核心思想 (什么是 `if`?)**
|
||||
|
||||
* **思路铺垫**
|
||||
|
||||
如果说顺序结构是一条单行道,那么**分支结构就像是在程序中设置了一个个十字路口。**当程序执行到这个路口时,它会根据一个特定的条件,来决定接下来该怎么走。
|
||||
|
||||
而 `if` 语句,就是我们在 C++ 中设置这个十字路口的工具。
|
||||
|
||||
* **`if` 语句的形态**
|
||||
|
||||
##### **形态一:`if` (单选 - 如果...就...)**
|
||||
|
||||
这是最简单的一个形态,它只关心**“如果条件满足,该做什么**。
|
||||
|
||||
* **语法结构**:
|
||||
|
||||
```cpp
|
||||
if (条件表达式) {
|
||||
// 如果 '条件表达式' 的结果为 true,
|
||||
// 就执行这里的代码。
|
||||
}
|
||||
// 如果为 false,则直接跳过花括号内的所有代码。
|
||||
```
|
||||
* **`条件表达式`**:这里的条件,通常是一个**关系运算**(如 `age > 18`)或**逻辑运算**(如 `score >= 60 && is_ok == false`)。它的最终计算结果必须是一个**布尔值**:`true` (真) 或 `false` (假)。
|
||||
* **`{ ... }`**:花括号内的部分,就是满足条件时要执行的代码。
|
||||
|
||||
##### **形态二:`if-else` (二选一 - 如果...就...否则...)**
|
||||
|
||||
很多时候,我们不仅关心条件满足时做什么,也关心条件**不满足**时做什么。
|
||||
|
||||
* **语法结构**:
|
||||
```cpp
|
||||
if (条件表达式) {
|
||||
// 条件为 true 时执行这里。
|
||||
} else {
|
||||
// 条件为 false 时执行这里。
|
||||
}
|
||||
```
|
||||
* **互斥关系**:`if` 代码块和 `else` 代码块是“有你没我”的。程序在一次判断中,**有且仅有**一个代码块会被执行。
|
||||
|
||||
|
||||
---
|
||||
|
||||
#### **3. 实例**
|
||||
|
||||
##### **案例:判断奇偶数 (演示 `if-else`)**
|
||||
|
||||
* **问题**:输入一个整数,判断它是奇数还是偶数。
|
||||
|
||||
* **逻辑**:一个数如果是偶数,那么它被2整除的余数必然是0。
|
||||
|
||||
* **代码实现**:
|
||||
```cpp
|
||||
if (number % 2 == 0) { // 条件:number除以2的余数是否为0?
|
||||
cout << "这是一个偶数。" << endl;
|
||||
} else {
|
||||
cout << "这是一个奇数。" << endl;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **4. 总结**
|
||||
|
||||
1. `if` 语句赋予了程序**决策能力**,是构建复杂逻辑的基础。
|
||||
2. `if` 用于单向判断,`if-else` 用于二选一,`if-else if-else` 用于多选一。
|
||||
3. `if` 括号中的条件必须是一个最终能得出 `true` 或 `false` 的表达式。
|
||||
4. `if - else if` 是**从上到下、依次判断、择一执行**的。
|
||||
5. 注意区分一个等号(**赋值运算符**)和两个等号(**关系运算符**)的区别!**判断是否相等,一定要用两个等号 `==`!**
|
||||
|
||||
* 如果你写了这样的条件判断语句:`if (score = 100)` ,那么会先执行`= 100`的赋值语句,让左侧 `score` 变量的值变为 `100`。最终括号里还剩下`if(score)`,也就等价于`if(100)`,而在 C++ 中,任何非零的整数在 `if` 的条件中都会被当作 `true`。所以,`if(100)` 就等同于 `if(true)`,这个 `if` 语句块**永远**都会被执行!
|
||||
Binary file not shown.
@@ -0,0 +1,182 @@
|
||||
### **C++ `if` 条件分支实战演练 讲义**
|
||||
|
||||
#### **一、 引言**
|
||||
|
||||
##### **问题引入:条件判断问题**
|
||||
|
||||
在编写程序时,经常会出现根据条件不同,所做的事情也不同的情况,例如:
|
||||
* **如果** 天在下雨,你**就**会带上雨伞
|
||||
* **否则**(也就是天没下雨),你**就**不带伞。
|
||||
|
||||
这个“如果...就...否则...”的过程,就是我们无时无刻不在进行的**决策**。我们会根据不同的**条件**(是否下雨),选择执行不同的**动作**(带伞或不带伞)。
|
||||
|
||||
程序可以通过 `if` 条件分支结构 来拥有这种在分岔点做选择的能力,使我们能够:
|
||||
|
||||
* **判断用户输入**:判断用户输入的数字是否在某个范围内、输入的是奇数还是偶数。
|
||||
* **做出决策**:根据不同的条件,执行完全不同的代码路径。
|
||||
* **响应变化**:例如根据游戏角色的血量,决定是继续攻击还是播放阵亡动画。
|
||||
|
||||
---
|
||||
|
||||
#### **二、 核心思想:如何解决条件判断问题**
|
||||
|
||||
对于一个需要条件判断的问题,我们有如下的解题模板(**==这是本讲义重要的部分,请务必理解!==**):
|
||||
|
||||
1. **【第一步:找到分岔点】**
|
||||
* 仔细阅读题目,找出决定程序走向的**所有关键条件**。这些就是程序需要做出选择的分岔点。
|
||||
* 例如:“判断奇偶性”的分岔点是“能否被2整除”;“判断成年人”的分岔点是“年龄是否大于等于18”。
|
||||
2. **【第二步:写出判断分岔点的条件语句】**
|
||||
* 将这些用自然语言描述的分岔点,翻译成 C++ **条件表达式**。
|
||||
* 例如:需要判断分数在70到80之间 -> `score >= 70 && score <= 80`。
|
||||
3. **【第三步:根据分岔点的数量和关系选择合适的`if`分支语句】**
|
||||
* **二选一**(是/否):用 `if-else` 结构。(例如:判断一个数是 奇数/偶数)
|
||||
* **只关心一种情况**:只用一个 `if` 结构。(例如:只有及格了才发奖状,不及格什么都不做)
|
||||
* **多选关系**:根据题意使用多个`if` 语句进行处理。(例如:学生考试评级为A、B、C 时分别要做不同的事情,那么就需要三个 `if` 语句, `if(score == 'A'){} if(score == 'B'){}; if(score == 'C'){};` 来分别处理每一种情况,其中 `score` 是储存考试评级的 `char` 变量)
|
||||
4. **【第四步:实现各分支的逻辑代码】**
|
||||
* 在搭建好 `if`、`else if` 与 `else` 的结构框架后,需要在其对应的 `{}` 代码块中,**实现**当该分支条件被满足时,程序所需执行的**具体逻辑**。包括但不限于:执行数学运算、对变量进行赋值,或者调用 `cout` 将计算结果等输出。
|
||||
|
||||
---
|
||||
|
||||
#### **三、 实战演练**
|
||||
|
||||
接下来,我们列出几个上课中所讲解的案例,来深化`if` 语句的使用。
|
||||
|
||||
##### **案例一:奇偶判断 (二选一)**
|
||||
|
||||
1. **分岔点**:一个数是“偶数”还是“奇数”。本质条件是“能否被2整除”。
|
||||
2. **写出判断分岔的条件语句**:`num % 2 == 0`。如果为`true`,说明是偶数。
|
||||
3. **分岔结构**:这是一个“是/否”二选一问题,使用 `if-else`。
|
||||
4. **程序代码**:
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
int num;
|
||||
cin >> num;
|
||||
if (num % 2 == 0) { // 如果“写出判断分岔的条件语句”为真
|
||||
cout << "偶数"; // 走“偶数”这条路
|
||||
} else {
|
||||
cout << "奇数"; // 否则,走“奇数”这条路
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
##### **案例二:景点门票 **
|
||||
|
||||
1. **分岔点**:票价是“半价”还是“全价”。条件是“年龄小于等于6” **或者** “年龄大于等于60”。
|
||||
2. **写出判断分岔的条件语句**:这里的连接词是“或者”,翻译成 C++ 就是 `||`。写出条件语句为:`age <= 6 || age >= 60`。
|
||||
3. **分岔结构**:二选一问题,使用 `if-else`。
|
||||
4. **程序代码**:
|
||||
```cpp
|
||||
if (age <= 6 || age >= 60) {
|
||||
cout << 25; // 半价
|
||||
} else {
|
||||
cout << 50; // 全价
|
||||
}
|
||||
```
|
||||
|
||||
##### **案例三:计算器 (多分支判断)**
|
||||
|
||||
**题目描述**:设计一个计算器。让用户输入**num1+num2**、**num1-num2**、**num1\*num2**、**num1/num2** 形式的计算式。
|
||||
|
||||
我们的计算器便能够自动识别此时是要进行加法运算、减法运算、乘法运算,还是除法运算。最终输出计算结果。
|
||||
|
||||
1. **分岔点**:用户想进行哪种运算?取决于输入的运算符是 `+`、`-`、`*` 还是 `/`。这是四个不同的岔路。
|
||||
2. **写出判断分岔的条件语句**:`ch == '+'`、`ch == '-'`、`ch == '*'`、`ch == '/'`。
|
||||
3. **分岔结构**:这里有多个独立的条件,每个条件都要做不同的事情,我们可以用一连串的 `if` 语句来分别检查。
|
||||
4. **程序代码**:
|
||||
```cpp
|
||||
int num1, num2;
|
||||
char ch;
|
||||
cin >> num1 >> ch >> num2;
|
||||
|
||||
if (ch == '+') {
|
||||
cout << num1 + num2;
|
||||
}
|
||||
if (ch == '-') {
|
||||
cout << num1 - num2;
|
||||
}
|
||||
if (ch == '*') {
|
||||
cout << num1 * num2;
|
||||
}
|
||||
if (ch == '/') {
|
||||
cout << (double)num1 / num2;
|
||||
}
|
||||
```
|
||||
|
||||
##### **案例四:闰年判断**
|
||||
|
||||
**题目描述:**请输入一个年份,判断该年是不是闰年。是的话输入该年份,不是的话输出"No"。其中能被4整除 **并且** 不能被100整除 **或者** 能被400整除 的是闰年。(这个判断条件稍显复杂,但是只要能写出判断分岔的条件语句,根据前面的条件判断问题解题模板,也能轻松解决。)
|
||||
|
||||
1. **分岔点**:这一年是“闰年”还是“平年”。
|
||||
2. **写出判断分岔的所有条件语句**
|
||||
|
||||
* 规则:(能被4整除 **并且** 不能被100整除) **或者** (能被400整除)。
|
||||
* 条件A(能被4整除):`year % 4 == 0`
|
||||
* 条件B(不能被100整除):`year % 100 != 0`
|
||||
* 条件C(能被400整除):`year % 400 == 0`
|
||||
* 将条件A, B, C组合起来,注意括号代表优先级:`(A && B) || C`
|
||||
* 最终写出判断分岔的条件语句:`((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)`
|
||||
3. **分岔结构**:二选一,用 `if-else`。
|
||||
4. **程序代码**:
|
||||
|
||||
```cpp
|
||||
int year;
|
||||
cin >> year;
|
||||
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
|
||||
cout << year; // 是闰年,输出年份
|
||||
} else {
|
||||
cout << "No"; // 不是闰年
|
||||
}
|
||||
```
|
||||
|
||||
##### **案例五:鸡兔同笼 **
|
||||
|
||||
**题目描述**:已知鸡和兔的总数量为n,总腿数为 m。输入 n 和 m ,依次输出鸡的数目和兔的数目。如果无解,则输出No answer。
|
||||
|
||||
本问题将编程与数学的结合起来了。我们需要根据程序计算出来的结果去**验证计算结果的合理性**。我们可以列出两个方程:
|
||||
|
||||
**$$ 鸡数量 + 兔数量 = n \ ①$$**
|
||||
|
||||
**$$ 2 * 鸡数量 + 4 * 兔数量 = m \ ②$$**
|
||||
|
||||
1. **分岔点**:根据给定的头和腿的数量,算出来的鸡兔数量来判断是“有解”还是“无解”。
|
||||
2. **写出判断分岔的条件语句**:列出方程后,进行变换后可以得到: `鸡 = (4*n-m)/2` 和 `兔 = n-鸡` 中,于是我们能推断出**无解**的条件:
|
||||
|
||||
* `4*n-m` 必须是偶数,否则鸡的数量是小数。 -> `(4*n-m) % 2 != 0`
|
||||
* 算出来的鸡的数量不能是负数。 -> `鸡 < 0`
|
||||
* 算出来的兔的数量不能是负数。 -> `兔 < 0`
|
||||
* 这三个**无解**的条件,**只要满足任意一个**,就说明无解。所以用 `||` 连接。
|
||||
* 最终写出判断分岔的条件语句:`( (4*n-m) % 2 != 0 || 鸡 < 0 || 兔 < 0 )`
|
||||
3. **分岔结构**:二选一,`if-else`。
|
||||
4. **程序代码**:
|
||||
|
||||
```cpp
|
||||
int n, m, chicken, rabbit;
|
||||
cin >> n >> m;
|
||||
|
||||
// 先用数学公式计算,对应方程 鸡 = (4*n-m)/2 和 兔 = n-鸡
|
||||
chicken = (4 * n - m) / 2;
|
||||
rabbit = n - chicken;
|
||||
|
||||
// 再用if进行合理性验证
|
||||
if ((4 * n - m) % 2 != 0 || chicken < 0 || rabbit < 0) {
|
||||
cout << "No answer";
|
||||
} else {
|
||||
cout << chicken << " " << rabbit;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **四、 总结**
|
||||
|
||||
* **掌握四步解题模板**:
|
||||
遇到条件判断问题。请遵循“**识别分岔点 -> 写出分岔点的条件表达式 -> 选择分支结构 -> 通过代码实现分支逻辑**”的流程,能确保你的思路清晰。
|
||||
|
||||
* **翻译条件表达式**:
|
||||
将自然语言条件翻译为代码的条件表达式要求熟练掌握,需要通过持续练习来巩固。
|
||||
|
||||
* **多使用括号**:
|
||||
在构建复杂的逻辑表达式时,使用 `()` 来指定运算优先级。能确保逻辑正确,也能让你的代码更加易于阅读。
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
### C++ if 条件分支 课后习题 - **答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 顺序结构
|
||||
2. 分支结构
|
||||
3. 条件 (或 条件表达式)
|
||||
4. `true` (真),`false` (假)
|
||||
5. 有且仅有
|
||||
6. `==`,`=`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. C 2. A 3. B 4. D 5. A 6. B 7. B 8. C 9. A 10. C
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √
|
||||
2. √
|
||||
3. √
|
||||
4. × (两者是互斥的,只能执行一个)
|
||||
5. × (判断相等必须用 `==`)
|
||||
6. √
|
||||
7. √
|
||||
8. × (这个是单向判断,用 `if` 就足够了)
|
||||
9. √
|
||||
10. √
|
||||
@@ -0,0 +1,83 @@
|
||||
### C++ if 条件分支 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 程序从上到下、一条一条依次执行的结构,叫做\_\_\_\_\_\_\_\_\_\_\_\_\_结构。
|
||||
2. 能够根据不同的情况做出不同反应的程序结构,叫做\_\_\_\_\_\_\_\_\_\_\_\_\_结构。
|
||||
3. `if` 语句它会根据括号中的\_\_\_\_\_\_\_\_\_\_\_\_\_,来决定接下来该走哪条路。
|
||||
4. `if (条件表达式)` 中,`条件表达式`的最终计算结果必须是一个布尔值,即\_\_\_\_\_\_\_\_\_\_\_\_\_或\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
5. `if-else` 结构是“有你没我”的互斥关系,程序在一次判断中,\_\_\_\_\_\_\_\_\_\_\_\_\_(填写 **可能** 或 **有且仅有**)会有一个代码块被执行。
|
||||
6. 在C++中,用来**判断**两个值是否相等的运算符是\_\_\_\_\_\_\_\_\_\_\_\_\_,用来**赋值**的运算符是\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 如果说顺序结构是一条单行道,那么分支结构就像是程序中的什么?
|
||||
A. 停车场 B. 收费站 C. 十字路口 D. 加油站
|
||||
|
||||
( ) 2. 观察下面的代码,当输入的 `score` 为 95 时,会输出什么?
|
||||
```cpp
|
||||
if (score >= 90) {
|
||||
cout << "优秀";
|
||||
}
|
||||
```
|
||||
A. 优秀 B. 良好 C. 95 D. 什么都不输出
|
||||
|
||||
( ) 3. 观察下面的代码,当输入的 `score` 为 85 时,会输出什么?
|
||||
```cpp
|
||||
if (score >= 90) {
|
||||
cout << "优秀";
|
||||
} else {
|
||||
cout << "继续努力";
|
||||
}
|
||||
```
|
||||
A. 优秀 B. 继续努力 C. 85 D. 什么都不输出
|
||||
|
||||
( ) 4. 要判断一个数 `n` 是不是偶数,`if` 括号中的条件表达式应该怎么写?
|
||||
A. `n % 2 == 1` B. `n % 2 = 0` C. `n / 2 == 0` D. `n % 2 == 0`
|
||||
|
||||
( ) 5. 在C++中,`if` 括号里的条件如果是 `if (100)`,计算机会把它当作什么来处理?
|
||||
A. `true` (真) B. `false` (假) C. 语法错误 D. 0
|
||||
|
||||
( ) 6. 在书本P37页 例3-5 洛谷团队系统的案例中,本地配置 `n` 道题的总时间是?
|
||||
A. `11 + 3 * n` B. `5 * n` C. `3 * n` D. `11 + 5 * n`
|
||||
|
||||
( ) 7. `if` 语句和 `if-else` 语句的主要区别是什么?
|
||||
A. `if` 只能判断一次,`if-else` 可以判断多次
|
||||
B. `if` 只管条件成立做什么,`if-else` 还管条件不成立做什么
|
||||
C. `if` 比 `if-else` 运行速度快
|
||||
D. `if` 后面必须有大括号,`if-else` 不用
|
||||
|
||||
( ) 8. 下面的代码存在一个错误,它会导致什么后果?
|
||||
```cpp
|
||||
int password = 123;
|
||||
if (password = 456) {
|
||||
cout << "登录成功";
|
||||
}
|
||||
```
|
||||
A. 程序无法编译 B. 条件判断永远为假 (false)
|
||||
C. 条件判断永远为真 (true) D. 程序会崩溃
|
||||
|
||||
( ) 9. 在 `if-else` 结构中,如果 `if` 后面的条件为 `true`,程序会怎么执行?
|
||||
A. 只执行 `if` 的代码块
|
||||
B. 只执行 `else` 的代码块
|
||||
C. `if` 和 `else` 的代码块都执行
|
||||
D. `if` 和 `else` 的代码块都不执行
|
||||
|
||||
( ) 10. “如果明天下雨,我就待在家里,否则我就去公园。” 这句话最适合用哪种程序结构来描述?
|
||||
A. 顺序结构 B. `if` 语句
|
||||
C. `if-else` 语句 D. 循环结构
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
( ) 1. 我们之前写的从上到下依次执行的代码,都属于顺序结构。
|
||||
( ) 2. `if` 语句可以在 C++ 中实现分支结构。
|
||||
( ) 3. `if (score >= 60)` 这个括号里的 `score >= 60` 是一个关系表达式。
|
||||
( ) 4. 在 `if-else` 结构中,`if` 部分和 `else` 部分的代码可能会同时被执行。
|
||||
( ) 5. 在判断一个数 `x` 是否等于10时,应该写成 `if (x = 10)`。
|
||||
( ) 6. 在C++中,任何非零的整数在 `if` 的条件中都会被当作 `true`。
|
||||
( ) 7. `if (a != b)` 这个条件是用来判断变量 `a` 和 `b` 的值是否不相等。
|
||||
( ) 8. “如果我的零花钱超过20元,我就去买一个冰淇淋。” 这个逻辑只能用 `if-else` 实现。
|
||||
( ) 9. 在“判断奇偶数”的案例中,如果一个数不是偶数,那么它一定是奇数。
|
||||
( ) 10. `if` 语句可以让我们的程序变得更智能,能够根据不同情况做出反应。
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
### C++ if 条件分支实战演练 课后习题 - **答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 分岔点 条件语句 数量 关系 逻辑代码
|
||||
2. `&&`
|
||||
3. `if-else`
|
||||
4. `||`
|
||||
5. 字符 (`char`)
|
||||
6. `ch - '0'`
|
||||
7. `(year % 4 == 0 && year % 100 != 0) || year % 400 == 0`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. A 2. C 3. C 4. B 5. B 6. C 7. C 8. C(还没讲if-else if -else) 9. B 10. C
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √
|
||||
2. × (错误的,`<= 80` 前缺少了 `score`)
|
||||
3. √ (例如计算器案例中,`+ - * /` 就是四种独立的情况)
|
||||
4. × (正好相反,先用数学公式计算,再用`if`来验证结果是否合理)
|
||||
5. √
|
||||
6. √ (这是良好的代码风格)
|
||||
7. × (因为使用的是多个独立的 `if`,程序会依次检查每一个 `if` 条件)
|
||||
8. √
|
||||
9. √
|
||||
10. √
|
||||
@@ -0,0 +1,66 @@
|
||||
### C++ if 条件分支实战演练 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. **解决条件判断问题的模板**的第一步是:找到需要程序做出选择的\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。第二步是:写出判断分岔点的\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。第三步是:根据分岔点的\_\_\_\_\_\_\_\_\_\_\_\_\_和\_\_\_\_\_\_\_\_\_\_\_\_\_选择合适的 `if` 分支语句。第四步是:实现各分支的\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
2. 在C++中,要表达“`score`在70到80之间(含边界)”这个条件,正确的代码是 `score >= 70` \_\_\_\_\_\_\_\_\_\_\_\_\_ `score <= 80`。
|
||||
3. 要判断一个数是“奇数”还是“偶数”,这是一个“二选一”问题,应该使用\_\_\_\_\_\_\_\_\_\_\_\_\_结构。
|
||||
4. 在“景点门票”案例中,半价的条件是“年龄小于等于6”**或者**“年龄大于等于60”,这里的“或者”应该用逻辑运算符\_\_\_\_\_\_\_\_\_\_\_\_\_来表示。
|
||||
5. 在“简单计算器”案例中,需要输入例如 `5+3` 这种格式的数据,那么 `cin >> num1 >> ch >> num2;` 这行代码可以依次读入一个整数、一个\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_(填一种数据类型)和一个整数。
|
||||
6. 在判断字符 `ch` 是否为数字时,我们可以通过表达式\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_将数字字符(如`'5'`)转换为它对应的整数数字(如`5`)。
|
||||
7. 闰年的判断规则是:`year` 能被4整除**并且**不能被100整除,**或者**能被400整除。请写出它的条件表达式:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. “如果一个数是3的倍数,就输出‘Yes’,否则什么也不做。”这个逻辑最适合用哪种结构?
|
||||
A. 一个 `if` 语句结构 B. `if-else` 结构 C. 多个 `if` 结构 D. 顺序结构
|
||||
|
||||
( ) 2. 判断一个字符 `ch` 是否为小写英文字母,正确的条件表达式是?
|
||||
A. `ch >= 'a' || ch <= 'z'` B. `ch > 'a' && ch < 'z'`
|
||||
C. `ch >= 'a' && ch <= 'z'` D. `ch == 'a'`
|
||||
|
||||
( ) 3. 在“简单计算器”案例中,如果想判断用户是否想做减法运算,`if` 的条件应该写成(`ch` 是字符类型变量,储存了运算符,例如`+-*/`)?
|
||||
A. `ch = '-'` B. `ch == "-"` C. `ch == '-'` D. `ch != '-'`
|
||||
|
||||
( ) 4. 在数学中 `70 <= score <= 80` 是正确的,但在C++中这种写法是错误的,因为它会先计算什么?
|
||||
A. `score <= 80` B. `70 <= score` C. `70 <= 80` D. 整个表达式一起计算
|
||||
|
||||
( ) 5. 在“鸡兔同笼”问题中,我们推断出无解的三个条件是“鸡的数量为小数”、“鸡的数量为负数”、“兔的数量为负数”。我们需要判断结果是否无解,那么这三个条件之间应该用什么逻辑运算符连接?
|
||||
A. `&&` (并且) B. `||` (或者) C. `!` (非) D. `==` (等于)
|
||||
|
||||
( ) 6. 在“景点门票”的例子中,景点的票价为50元/人,一个6岁的孩子和一个60岁的老人去买票,根据条件 `age <= 6 || age >= 60`,他们的票价分别是多少?
|
||||
A. 25元 和 50元 B. 50元 和 25元 C. 25元 和 25元 D. 50元 和 50元
|
||||
|
||||
( ) 7. 要判断“一个数 `x` 同时是3和5的倍数”,正确的表达式是?
|
||||
A. `x % 3 == 0 || x % 5 == 0`
|
||||
B. `x % 3 && x % 5 == 0`
|
||||
C. `x % 3 == 0 && x % 5 == 0`
|
||||
D. `x % 15 != 0`
|
||||
|
||||
( ) 8. “输入一个整数,如果是正数,输出‘Positive’;如果是负数,输出‘Negative’;如果是0,输出‘Zero’。” 这个问题最好用什么结构来解决?
|
||||
A. 一个 `if` B. 一个 `if-else` C. 多个独立的 `if` D. `if-else if-else` 结构
|
||||
|
||||
( ) 9. 给出三角形的三条边长 L1、L2、L3 输出判断能否构成三角形。如果三条边长分别是 `L1=3, L2=4, L3=8`,程序判断的结果应该是?
|
||||
A. 可以构成三角形,因为三条边都是正数
|
||||
B. 不可以构成三角形,因为 `L1 + L2` 不大于 `L3`
|
||||
C. 可以构成三角形,因为 `L1 + L3` 大于 `L2`
|
||||
D. 不可以构成三角形,因为三条边不一样长
|
||||
|
||||
( ) 10. 在构建复杂的逻辑表达式时,如果搞不清楚 `&&` 和 `||` 的优先级,最好的习惯是什么?
|
||||
A. 把 `&&` 写在前面 B. 把 `||` 写在前面
|
||||
C. 使用括号 `()` 来明确指定运算顺序 D. 查阅C++手册
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. 解决条件判断问题,可以套用四步解题模板。
|
||||
( ) 2. `if(score >= 70 && <= 80)` 是一个合法的C++判断语句。
|
||||
( ) 3. 多个独立的 `if` 语句可适用于处理几种互不相关的条件。
|
||||
( ) 4. 在“鸡兔同笼”问题中,`if` 语句主要用来进行数学计算,而不是合理性验证。
|
||||
( ) 5. 判断“一个数 `x` 是奇数”的条件是 `x % 2 != 0`。
|
||||
( ) 6. 为了让代码更清晰易读,`if` 和 `else` 后面大括号里的语句应该向内缩进。
|
||||
( ) 7. 在“简单计算器”的例子中,如果输入的是 `5+3`,程序在执行完加法的 `if` 语句后,就不会再去判断后面的减法、乘法、除法的 `if` 语句了。
|
||||
( ) 8. 构成三角形的条件是“任意两边之和大于第三边”,所以三个“大于”条件必须同时满足,应该用 `&&` 连接。
|
||||
( ) 9. 解决条件判断问题的步骤之一是将生活中的语言翻译成计算机能懂的条件表达式。
|
||||
( ) 10. “判断一个英文字符是元音还是辅音”是一个“二选一”问题,适合用 `if-else` 结构。
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -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. **重视书写顺序**:
|
||||
在多分支结构中,通常应优先将**最严格、最特殊**的条件放在前面,并善于利用结构自带的隐含的条件来精简后续的判断逻辑。
|
||||
Binary file not shown.
+93
@@ -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. **注意代码缩进**:在编写嵌套代码时,必须使用规范的缩进,以清晰地展示代码的层级关系,否则代码将变得难以阅读和维护。
|
||||
BIN
Binary file not shown.
+34
@@ -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` 的代码块内均可)
|
||||
+100
@@ -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` 的代码块中。
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
+157
@@ -0,0 +1,157 @@
|
||||
### **C++ `switch` 多选择语句 讲义**
|
||||
|
||||
#### **1. 引言**
|
||||
|
||||
* **问题引入:多分支选择的困境**
|
||||
|
||||
在之前的学习中,我们掌握了 `if-else if-else` 结构,它能帮助我们处理各种复杂的判断。例如,设计一个“自动贩猫机”,根据投入的金额,输出对应的猫咪:
|
||||
|
||||
```cpp
|
||||
if (n == 9) {
|
||||
cout << "小白";
|
||||
} else if (n == 8) {
|
||||
cout << "小黑";
|
||||
} else if (n == 6) {
|
||||
cout << "小棕";
|
||||
} else if (n == 4) {
|
||||
cout << "小灰";
|
||||
} else {
|
||||
cout << "无";
|
||||
}
|
||||
```
|
||||
这段代码功能正确,但当选项非常多时,一长串的 `else if` 会显得有些重复和臃肿。我们不禁会想:对于这种**只针对同一个变量进行等值判断**的场景,有没有更清晰、更结构化的写法呢?
|
||||
|
||||
* **解决方案:`switch` 语句**
|
||||
|
||||
答案是肯定的。C++ 为这类“多路等值选择”场景,提供了一个专门的解决方案——`switch` 语句。它能让我们的代码意图一目了然,极大地提高代码的可读性。
|
||||
|
||||
* **学习目标**:
|
||||
1. 理解 `switch` 语句与 `if-else if` 在逻辑上的核心区别。
|
||||
2. 掌握 `switch`, `case`, `break`, `default` 四个关键字的语法和作用。
|
||||
3. 深刻理解并规避 `switch` 语句最常见的陷阱——“case穿透”。
|
||||
4. 学会利用 `switch` 的特性合并相似逻辑,编写简洁高效的代码。
|
||||
|
||||
---
|
||||
|
||||
#### **2. 核心思想**
|
||||
|
||||
`if-else if` 和 `switch` 的工作方式有着本质的不同:
|
||||
|
||||
* **`if-else if` 的逻辑是“顺序比较”**:
|
||||
它像一个哨兵,拿着一个值,从第一个条件开始逐一盘问:“你是9吗?”、“你是8吗?”、“你是6吗?”... 直到找到匹配的条件或者走到最后的 `else`。这是一个**串行**的过程。
|
||||
|
||||
* **`switch` 的逻辑是“直接跳转”**:
|
||||
它更像一个“对号入座”系统。`switch` 会先看一下变量的值(比如是8),然后直接在内部的“情况列表 (`case`)”中找到值为8的标签,并**直接跳转**到该位置开始执行代码。这是一个**直接**的过程,在选项很多时通常效率更高。
|
||||
|
||||
---
|
||||
|
||||
#### **3. 语法详解 (构成与规则)**
|
||||
|
||||
我们来看一下 `switch` 语句的完整、规范的结构:
|
||||
|
||||
```cpp
|
||||
switch (表达式) {
|
||||
case 常量值1:
|
||||
// 当'表达式'的值等于'常量值1'时,执行此处的代码
|
||||
break;
|
||||
case 常量值2:
|
||||
// 当'表达式'的值等于'常量值2'时,执行此处的代码
|
||||
break;
|
||||
// ...可以有任意多个case...
|
||||
default:
|
||||
// 当'表达式'的值与上面所有case都不匹配时,执行此处的代码
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
* **关键字剖析**:
|
||||
* **`switch (表达式)`**: 这里的“表达式”是我们要判断的变量或计算结果,它的值必须是**整数类型**(如 `int`, `char`, `bool` 等)。
|
||||
* **`case 常量值:`**: 每个 `case` 都是一个“路牌”或“标签”。`case` 后面必须跟一个**常量**(如 `8`, `'A'`),不能是变量。程序会用 `switch` 表达式的值与这些常量值进行匹配。
|
||||
* **`break;`**: **这是 `switch` 语句的刹车**。当一个 `case` 的代码块执行完毕后,`break` 会立即终止并跳出整个 `switch` 结构。**如果缺少 `break`,将会引发“case穿透”**。
|
||||
* **`default:`**: 这是一个**可选**的“默认”或“其他”分支。如果表达式的值与所有 `case` 都不匹配,程序就会执行 `default` 下的代码块。它功能上类似于 `if-else if` 链条中最后的那个 `else`。
|
||||
|
||||
---
|
||||
|
||||
#### **4. 关键机制与技巧**
|
||||
|
||||
##### **陷阱:“Case穿透”**
|
||||
|
||||
让我们回到“贩猫机”的例子,如果我们在写 `switch` 时,忘记了写 `break`,会发生什么?
|
||||
|
||||
```cpp
|
||||
// 错误的示例 - 忘记写 break
|
||||
int n = 8;
|
||||
switch(n) {
|
||||
case 9:
|
||||
cout << "小白";
|
||||
case 8:
|
||||
cout << "小黑"; // 程序会从这里开始执行
|
||||
case 6:
|
||||
cout << "小棕";
|
||||
case 4:
|
||||
cout << "小灰";
|
||||
default:
|
||||
cout << "无";
|
||||
}
|
||||
// 最终输出: 小黑小棕小灰无
|
||||
```
|
||||
|
||||
* **执行分析**:
|
||||
1. `switch(n)` 发现 `n` 的值是 `8`。
|
||||
2. 程序直接**跳转**到 `case 8:` 标签处。
|
||||
3. 执行 `cout << "小黑";`。
|
||||
4. **由于 `case 8` 后面没有 `break`,程序不会停止!** 它会无视下面的 `case 6:`、`case 4:` 等标签,像一辆失控的汽车一样,继续向下执行所有代码,直到遇到一个 `break` 或者 `switch` 结构的末尾。
|
||||
5. 因此,它会接着执行 `cout << "小棕";`、`cout << "小灰";` 和 `cout << "无";`。
|
||||
|
||||
**结论**:忘记写 `break` 是 `switch` 语句中最常见的逻辑错误。**请养成写完一个 `case` 的逻辑后,立即补上 `break` 的好习惯。**
|
||||
|
||||
##### **合并相似分支:有意利用“穿透”**
|
||||
|
||||
虽然“穿透”通常是 Bug 的来源,但我们也可以巧妙地利用它来简化代码。当多个不同的 `case` 需要执行完全相同的操作时,我们可以将它们堆叠在一起。
|
||||
|
||||
* **案例**:判断输入的字母是元音还是辅音。
|
||||
|
||||
```cpp
|
||||
char letter = 'i';
|
||||
switch (letter) {
|
||||
// 对于 a, e, i, o, u 这五种情况,都执行相同的逻辑
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
cout << "是元音字母" << endl;
|
||||
break; // 执行完后跳出
|
||||
default:
|
||||
cout << "是辅音字母" << endl;
|
||||
break;
|
||||
}
|
||||
// 输出: 是元音字母
|
||||
```
|
||||
在这个例子中,当 `letter` 是 `i` 时,程序跳转到 `case 'i':`,因为前面没有任何 `break`,它会一直“穿透”下去,直到 `case 'u':` 之后,执行 `cout << "是元音字母" << endl;`,然后 `break`。这种写法清晰地表达了“对于这一组情况,执行相同的操作”的意图。
|
||||
|
||||
---
|
||||
|
||||
#### **5. 使用场景与限制 (`switch` 和 `if-else if`)**
|
||||
|
||||
`switch` 并非 `if-else if` 的完全替代品,它有自己的使用领域。
|
||||
|
||||
| 特性 | `switch` 语句 | `if-else if-else` 语句 |
|
||||
| :------------ | :----------------------------------------------- | :------------------------------------------------------ |
|
||||
| **比较类型** | 只能进行**等于 (==)** 的比较 | 可以进行任意逻辑条件的比较 (`>`, `<`, `!=`, `&&`, `||`) |
|
||||
| **判断变量** | 必须是**同一个**变量或表达式 | 每次判断的条件可以完全不同 |
|
||||
| **`case` 值** | 必须是**整型或字符型常量** | 条件中的值可以是变量,类型不限 |
|
||||
| **适用场景** | **等值判断(就是判断是否与某个值相等)** | **区间判断**、**复杂逻辑组合**、所有通用判断场景 |
|
||||
| **可读性** | 在处理多个等值选择时,结构更清晰,可读性**更高** | 分支过多或条件复杂时,可读性可能下降 |
|
||||
|
||||
**简单总结**:当你需要判断一个变量**等于**哪个**具体常量值**时,`switch` 是更优的选择。而在进行**范围判断**(如 `score > 90`)或**复合条件判断**时,必须使用 `if-else if`。
|
||||
|
||||
---
|
||||
|
||||
#### **6. 总结**
|
||||
|
||||
1. **功能定位**:`switch` 是处理**多路等值选择**的专用结构,比 `if-else if` 更清晰、高效。
|
||||
2. **`break` **:务必为每个独立的 `case` 分支添加 `break`,以防止意外的“case穿透”。
|
||||
3. **合并 `case`**:当多个情况执行相同逻辑时,可以利用“穿透”特性将它们分组,以简化代码。
|
||||
4. **`default` 保底**:总是提供一个 `default` 分支来处理所有未预料到的情况,这能让你的程序更加健壮。
|
||||
5. **明确限制**:记住 `switch` 只能用于整型/字符型变量的等值判断,不能用于范围和复杂逻辑。
|
||||
BIN
Binary file not shown.
+35
@@ -0,0 +1,35 @@
|
||||
### 参考答案
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 对号入座 (或 直接跳转)
|
||||
2. `case`
|
||||
3. `break`
|
||||
4. `default`
|
||||
5. case 穿透
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. B
|
||||
2. B (从 `case 2` 开始穿透到 `case 3`,但 `case 3` 后面没有 `default`,到此为止)
|
||||
3. C
|
||||
4. C
|
||||
5. B
|
||||
6. C
|
||||
7. B
|
||||
8. C
|
||||
9. B (从 `case 'B'` 开始,穿透到 `case 'C'`,遇到 `break` 停止)
|
||||
10. B
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √
|
||||
2. × (`default` 分支是可选的)
|
||||
3. × (`case` 后面必须跟一个常量)
|
||||
4. √
|
||||
5. √
|
||||
6. × (`switch` 不能做范围判断,所以 `if` 更通用)
|
||||
7. √
|
||||
8. × (这是逻辑错误,不是编译错误,程序能正常运行但结果可能不符合预期)
|
||||
9. √
|
||||
10. √ (这被称为嵌套 `switch`,是合法的)
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
### C++ switch 多选择语句 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `if-else if` 的逻辑是“顺序比较”,而 `switch` 的逻辑是“**\_\_\_\_\_\_\_\_\_\_\_\_\_**”,在选项多时效率更高。
|
||||
|
||||
2. `switch` 语句中,每个选项都由关键字 **\_\_\_\_\_\_\_\_\_\_\_\_\_** 开头,后面跟一个常量值和冒号。
|
||||
|
||||
3. 为了防止“case 穿透”,在每个独立的 `case` 代码块结束时,都应该加上 **\_\_\_\_\_\_\_\_\_\_\_\_\_** 语句。
|
||||
|
||||
4. 如果 `switch` 表达式的值与所有 `case` 都不匹配,程序会执行 **\_\_\_\_\_\_\_\_\_\_\_\_\_** 分支下的代码。
|
||||
|
||||
5. 一个 `case` 后面忘记写 `break`,程序会继续向下执行之后的所有代码,这种现象叫做“**\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_**”。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 阅读代码,当输入为 `2` 时,输出结果是什么?
|
||||
```cpp
|
||||
int n;
|
||||
cin >> n;
|
||||
switch(n) {
|
||||
case 1: cout << "Apple"; break;
|
||||
case 2: cout << "Banana"; break;
|
||||
case 3: cout << "Cherry"; break;
|
||||
}
|
||||
```
|
||||
A. Apple B. Banana C. Cherry D. 没有输出
|
||||
|
||||
( ) 2. 阅读代码,当输入为 `2` 时,输出结果是什么? (注意:缺少 `break`)
|
||||
```cpp
|
||||
int n;
|
||||
cin >> n;
|
||||
switch(n) {
|
||||
case 1: cout << "A";
|
||||
case 2: cout << "B";
|
||||
case 3: cout << "C";
|
||||
}
|
||||
```
|
||||
A. B B. BC C. ABC D. C
|
||||
|
||||
( ) 3. 阅读代码,当输入为 `5` 时,输出结果是什么?
|
||||
```cpp
|
||||
int n;
|
||||
cin >> n;
|
||||
switch(n) {
|
||||
case 1: cout << "A"; break;
|
||||
case 2: cout << "B"; break;
|
||||
default: cout << "Other";
|
||||
}
|
||||
```
|
||||
A. A B. B C. Other D. 没有输出
|
||||
|
||||
( ) 4. `switch` 语句主要用来替代哪种结构的 `if` 语句?
|
||||
A. `if (score > 90)`
|
||||
B. `if (a > 0 && b > 0)`
|
||||
C. `if (day == 1) { ... } else if (day == 2) { ... } else if (day == 3) { ... }`
|
||||
D. `if (password != "123")`
|
||||
|
||||
( ) 5. 下列哪种判断**不能**直接用 `switch` 语句实现?
|
||||
A. 判断某天是周几 B. 判断成绩是否及格
|
||||
C. 判断输入的字符是不是 'Y' D. 判断用户的选择是不是 1
|
||||
|
||||
( ) 6. `switch (n)` 中,`n` 的结果**不能**是什么类型?
|
||||
A. `int` B. `char` C. `double` D. `bool`
|
||||
|
||||
( ) 7. 在 `switch` 结构中,`default` 关键字的作用是?
|
||||
A. 提供一个默认的变量值 B. 当所有 `case` 都不匹配时执行
|
||||
C. 必须写在 `switch` 的最开始 D. 用来结束 `switch` 语句
|
||||
|
||||
( ) 8. 为了判断一个字符 `c` 是不是元音字母(a, e, i, o, u),最高效的 `switch` 写法是?
|
||||
A. 为 a, e, i, o, u 分别写五个独立的 `case`,每个都带 `break`
|
||||
B. 使用 `if (c=='a' || c=='e' ...)`
|
||||
C. 将 `case 'a': case 'e': case 'i': case 'o': case 'u':` 堆叠在一起,共享一个代码块
|
||||
D. `switch` 无法实现此功能
|
||||
|
||||
( ) 9. 阅读代码,当输入为 `'B'` 时,输出结果是什么?
|
||||
```cpp
|
||||
char c;
|
||||
cin >> c;
|
||||
switch(c) {
|
||||
case 'A': cout << "Apple";
|
||||
case 'B': cout << "Banana";
|
||||
case 'C': cout << "Cherry"; break;
|
||||
case 'D': cout << "Durian";
|
||||
}
|
||||
```
|
||||
A. Banana B. BananaCherry C. BananaCherryDurian D. Cherry
|
||||
|
||||
( ) 10. `case` 标签后面跟的值必须是?
|
||||
A. 一个变量 B. 一个常量 C. 一个表达式 D. 一个函数
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. `switch` 语句只能用于进行“等于”的判断。
|
||||
( ) 2. 在 `switch` 语句中,`default` 分支是必须存在的,不能省略。
|
||||
( ) 3. `case` 后面跟的可以是 `case x:`,其中 `x` 是一个 `int` 类型的变量。
|
||||
( ) 4. `break` 语句的作用是跳出当前的 `switch` 结构。
|
||||
( ) 5. 如果好几个 `case` 需要执行的操作完全一样,可以利用“case穿透”来简化代码。
|
||||
( ) 6. `if-else if` 语句能实现的功能,`switch` 语句也一定能实现。
|
||||
( ) 7. `switch` 语句中,各个 `case` 标签的顺序不影响最终的逻辑结果(假设都正确使用了 `break`)。
|
||||
( ) 8. 忘记在 `case` 中写 `break` 会导致编译错误(CE)。
|
||||
( ) 9. `switch` 的逻辑是“直接跳转”,而 `if-else if` 是“顺序比较”。
|
||||
( ) 10. 可以在一个 `switch` 结构中,放置另一个 `switch` 结构。
|
||||
BIN
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,258 @@
|
||||
## **C++ 分支结构综合 练习题**
|
||||
|
||||
## **姓名:\_\_\_\_\_\_\_\_\_\_** **成绩:\_\_\_\_\_\_\_\_\_\_**
|
||||
|
||||
#### **一、 填空题 (每空 2 分,共 14 分)**
|
||||
|
||||
1. 在 `switch` 语句中,如果所有 `case` 标签都未匹配成功,程序将执行 \_\_\_\_\_\_\_\_\_\_\_\_\_ 标签后的代码(如果存在)。
|
||||
2. 要在一个 `if` 或者 `else` 代码块中执行多条指令,必须使用一对 \_\_\_\_\_\_\_\_\_\_\_\_\_ 将它们包裹起来。
|
||||
3. 在 `switch(c)` 语句中,变量`c`的类型不能是 `double` 或者 \_\_\_\_\_\_\_\_\_\_\_\_\_ 类型。
|
||||
4. 要判断一个年份 `year` 是“闰年”(能被4整除但不能被100整除,或者能被400整除),其完整的 C++ 逻辑表达式为 \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
5. 在C++中,用于判断“不等于”的关系运算符是 \_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
6. `if-else if-else` 结构特别适合用于处理多个互斥的条件分支,当其中某一个条件满足后,其余的 \_\_\_\_\_\_\_\_\_\_\_\_\_ 将不会再被判断。
|
||||
7. 表达式 `x > 10` 的逻辑非形式是 `!(__________________)`。
|
||||
|
||||
#### **二、 单项选择题 (每题 2 分,共 20 分)**
|
||||
|
||||
( ) 1. C++ 中用于从键盘读取用户输入的工具是?
|
||||
A. `cout` B. `main` C. `cin` D. `return`
|
||||
|
||||
( ) 2. 根据年龄 `age` 来决定不同的票价:儿童(<12岁)半价,老人(>=60岁)7折,其他人全价。这个逻辑最适合用什么结构实现?
|
||||
A. 顺序执行 B. `if...else if...else` C. 单个 `if` D. `switch`
|
||||
|
||||
( ) 3. `switch` 语句的括号里,不可以放入哪种类型的变量?
|
||||
A. `int` B. `char` C. `bool` D. `double`
|
||||
|
||||
( ) 4. 对于 `switch` 语句,下列说法正确的是?
|
||||
A. `default` 语句是必须的
|
||||
B. `case` 后面可以跟一个变量,如 `case x:`
|
||||
C. `break` 的作用是防止穿透到下一个 `case`
|
||||
D. `switch` 语句可以判断一个浮点数的范围
|
||||
|
||||
( ) 5. 如果有定义 `int score = 85;`,表达式 `score >= 60 && score < 90` 的结果是?
|
||||
A. `true` B. `false` C. 85 D. 60
|
||||
|
||||
( ) 6. 判断“如果今天是周末,再进一步判断天气是否晴朗”这样的逻辑,最适合用什么结构?
|
||||
A. `switch` B. 多个独立的 `if` C. `if-else` D. 嵌套的 `if`
|
||||
|
||||
( ) 7. 分析代码,若 `score = 50`,程序会执行哪个分支?
|
||||
`if (score >= 60) { ... } else if (score >= 80) { ... } else { ... }`
|
||||
A. 执行 `score >= 60` 的分支 B. 执行 `score >= 80` 的分支
|
||||
C. 执行 `else` 分支 D. 没有任何分支被执行
|
||||
|
||||
( ) 8. 下列哪个不是C++的关键字,可以作为变量名?
|
||||
A. `double` B. `total_Count` C. `if` D. `case`
|
||||
|
||||
( ) 9. 表达式 `20 / 3` 和 `20 % 3` 的结果分别是?
|
||||
A. 6.67 和 2 B. 6 和 2 C. 6 和 1 D. 7 和 2
|
||||
|
||||
( ) 10. 判断一个整数 `num` 是奇数,正确的 C++ 表达式是?
|
||||
A. `num % 2 == 0` B. `num % 2 == 1` C. `num / 2 == 1` D. `num / 2 != 0`
|
||||
|
||||
#### **三、 判断题 (每题 2 分,共 20 分,对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. 在 `if-else` 结构中,`if` 代码块和 `else` 代码块有可能同时被执行。
|
||||
( ) 2. 赋值运算符 `=` 和关系运算符 `==` 在 `if` 条件中作用相同,可以混用。
|
||||
( ) 3. 在 `if (A || B)` 这个条件中,如果 `A` 的结果已经是 `true`,那么程序将不再去判断 `B` 的真假。
|
||||
( ) 4. `switch` 语句的每个 `case` 分支都必须以 `break` 结尾。
|
||||
( ) 5. 一个 `if` 语句可以不包含 `else if` 或 `else` 部分。
|
||||
( ) 6. 在C++中,书写 `if (x > 10 && < 20)` 是一个合法且正确的判断 `x` 范围的方式。
|
||||
( ) 7. `else` 总是与和它在同一代码块中,且离它最近的那个未配对的 `if` 结合。
|
||||
( ) 8. 表达式 `!false || false` 的结果是 `true`。
|
||||
( ) 9. 在 `switch` 语句中,可以合并多个 `case`来执行相同的代码块。
|
||||
( ) 10. `if...else if...else` 结构中,只会有一个代码块被执行。
|
||||
|
||||
#### **四、 代码阅读与分析题 (每题 4 分,共 16 分)**
|
||||
请直接在代码下方的横线处写出代码运行后的输出结果(如果程序没有任何输出,则写“无输出”)。
|
||||
|
||||
1. **字符与整数运算**
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
char c = 'C'; // 'C'的ASCII码是67
|
||||
c = c + 3;
|
||||
cout << c << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
输出结果:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
2. **多分支逻辑**
|
||||
```cpp
|
||||
int main() {
|
||||
int temperature = -5;
|
||||
if (temperature > 30) {
|
||||
cout << "炎热";
|
||||
} else if (temperature > 15) {
|
||||
cout << "温暖";
|
||||
} else if (temperature > 0) {
|
||||
cout << "寒冷";
|
||||
} else {
|
||||
cout << "冰冻";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
输出结果:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
3. **switch**
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
char grade = 'B';
|
||||
switch (grade) {
|
||||
case 'A':
|
||||
cout << "优秀 ";
|
||||
break;
|
||||
case 'B':
|
||||
cout << "良好 ";
|
||||
case 'C':
|
||||
cout << "中等 ";
|
||||
break;
|
||||
case 'D':
|
||||
cout << "及格 ";
|
||||
default:
|
||||
cout << "需努力";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
输出结果:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
4. **嵌套if**
|
||||
```cpp
|
||||
int main() {
|
||||
bool logged_in = true;
|
||||
bool is_admin = false;
|
||||
if (logged_in) {
|
||||
if (is_admin) {
|
||||
cout << "欢迎管理员";
|
||||
} else {
|
||||
cout << "欢迎普通用户";
|
||||
}
|
||||
} else {
|
||||
cout << "请先登录";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
输出结果:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
|
||||
#### **五、 程序填空题(本大题共 30 分)**
|
||||
|
||||
1. **题目:成绩等级转换 (共 8 分)**
|
||||
要求:输入一个整数 `score` 代表成绩。根据以下规则使用 `if-else if-else` 结构输出对应的等级。
|
||||
|
||||
* 90 ~ 100分: "A"
|
||||
* 80 ~ 89分: "B"
|
||||
* 70 ~ 79分: "C"
|
||||
* 60 ~ 69分: "D"
|
||||
* 60分以下: "F"
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
int score;
|
||||
cout << "请输入学生成绩: ";
|
||||
cin >> score;
|
||||
|
||||
if (score >= 90) {
|
||||
cout << "A";
|
||||
}
|
||||
// 1. 判断 B 等级 (80 ~ 89)
|
||||
else if (__________________________) {
|
||||
cout << "B";
|
||||
}
|
||||
// 2. 判断 C 等级 (70 ~ 79)
|
||||
else if (__________________________) {
|
||||
cout << "C";
|
||||
}
|
||||
// 3. 判断 D 等级 (60 ~ 69)
|
||||
else if (__________________________) {
|
||||
cout << "D";
|
||||
}
|
||||
// 4. 其他情况都为 F
|
||||
________________ {
|
||||
cout << "F";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
2. **题目:星期转换器(共 8 分)**
|
||||
要求:输入一个1-7的整数 `day`,使用 `switch` 语句输出对应的英文星期(1对应"Monday",2对应"Tuesday" ... 7对应"Sunday")。如果输入其他数字,输出"Invalid day"。
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
int day;
|
||||
cout << "请输入1-7的数字: ";
|
||||
cin >> day;
|
||||
|
||||
// 1. 请根据题意在此处填写一种分支结构类型进行判断
|
||||
________________{
|
||||
case 1:
|
||||
cout << "Monday";
|
||||
// 2.此处应填写?
|
||||
________________;
|
||||
case 2:
|
||||
cout << "Tuesday";
|
||||
break;
|
||||
// 3. 请补充星期三(Wednesday)的判断
|
||||
________________:
|
||||
cout << "Wednesday";
|
||||
break;
|
||||
case 4: cout << "Thursday"; break;
|
||||
case 5: cout << "Friday"; break;
|
||||
case 6: cout << "Saturday"; break;
|
||||
case 7: cout << "Sunday"; break;
|
||||
// 4. 处理无效输入的情况
|
||||
________________:
|
||||
cout << "Invalid day";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
3. **题目:商场折扣计算器**
|
||||
要求:根据顾客的消费金额 `amount` 和他是否为VIP会员 `is_vip` 来计算最终需要支付的金额。
|
||||
|
||||
* **折扣规则**:
|
||||
* VIP会员(`is_vip`为`true`)可以享受折扣。折扣力度取决于消费金额:
|
||||
* 如果消费金额 `amount` **大于500元**,VIP会员享受 **8折** 优惠。
|
||||
* 如果消费金额**小于或等于500元**,VIP会员享受 **9折** 优惠。
|
||||
* 非VIP会员(`is_vip`为`false`)**不享受任何折扣**。
|
||||
|
||||
**请根据以上规则,完成代码,计算完最终应付金后直接输出即可。**
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
double amount;
|
||||
bool is_vip;
|
||||
cout << "请输入消费金额和是否为VIP(1是/0否): ";
|
||||
cin >> amount >> is_vip;
|
||||
// 请自行使用合适的分支结构,来根据 消费金额 和 是否为VIP会员 计算总运费(本大题按完成度与步骤给分,请将完整的解题代码写在下方,本题答案不唯一,代码实现能达到题目要求即可)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Binary file not shown.
@@ -0,0 +1,94 @@
|
||||
### **C++ (分支结构综合) 模拟练习题 - 参考答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `default`
|
||||
2. `大括号` (或 `{}`)
|
||||
3. `string` (或 `float`, `double` 等其他非整型)
|
||||
4. `(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)`
|
||||
5. `!=`
|
||||
6. `分支` (或 `条件`, `else if`/`else`)
|
||||
7. `x <= 10`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **C** (cin 用于输入)
|
||||
2. **B** (if-else if-else 用于多区间判断)
|
||||
3. **D** (switch 不支持浮点数)
|
||||
4. **C** (break 用于防止 case 穿透)
|
||||
5. **A** (85 大于等于60且小于90,为真)
|
||||
6. **D** (前置条件下的再判断,是典型的嵌套逻辑)
|
||||
7. **C** (50不满足前两个条件,执行 else)
|
||||
8. **B** (total\_Count 是合法的变量名)
|
||||
9. **B** (整数除法 `20/3` 得 6,取余 `20%3` 得 2)
|
||||
10. **B** (奇数除以2余数为1)
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. **×** (if-else 结构是互斥的)
|
||||
2. **×** (`=` 是赋值,`==` 是比较)
|
||||
3. **√** (逻辑或 || 的短路特性)
|
||||
4. **×** (break 不是必须的,但是省略会产生穿透效果)
|
||||
5. **√** (if 可以独立存在)
|
||||
6. **×** (语法错误,应写为 `x > 10 && x < 20`)
|
||||
7. **√** (这是多分支 "else" 问题的配对规则)
|
||||
8. **√** (`!false` 是 `true`,`true || false` 结果为 `true`)
|
||||
9. **√** (可以将多个 case 标签写在一起,共用一个执行块)
|
||||
10. **√** (该结构具有排他性,最多只有一个分支被执行)
|
||||
|
||||
#### **四、 代码阅读与分析题**
|
||||
|
||||
1. **F** (字符'C'的ASCII码67, 67+3=70, 70对应的ASCII字符是'F')
|
||||
2. **冰冻** (-5不满足前三个条件,执行最后的 else)
|
||||
3. **良好 中等** (匹配 `case 'B'`,输出"良好 ",因无break,穿透到`case 'C'`,输出"中等 ",遇到break结束)
|
||||
4. **欢迎普通用户** (`logged_in`为真,执行外层if;`is_admin`为假,执行内层else)
|
||||
|
||||
#### **五、 程序填空题**
|
||||
|
||||
1. **题目:成绩等级转换**
|
||||
1. `score >= 80`
|
||||
2. `score >= 70`
|
||||
3. `score >= 60`
|
||||
4. `else`
|
||||
|
||||
2. **题目:星期转换器**
|
||||
1. `switch(day)`
|
||||
2. `break`
|
||||
3. `case 3`
|
||||
4. `default`
|
||||
|
||||
3. **题目:商场折扣计算器**
|
||||
*(注意:这是一个开放性编程题,以下为标准参考答案,学生的实现逻辑正确即可)*
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
double amount;
|
||||
bool is_vip;
|
||||
cout << "请输入消费金额和是否为VIP(1是/0否): ";
|
||||
cin >> amount >> is_vip;
|
||||
|
||||
double final_payment = amount; // 默认应付金额为原始金额
|
||||
|
||||
// 8. 外层首先判断是否为VIP会员
|
||||
if (is_vip == true) { // 或者直接 if (is_vip)
|
||||
// 是VIP会员,进入嵌套判断来决定折扣力度
|
||||
|
||||
// 9. 嵌套判断:消费金额是否大于500
|
||||
if (amount > 500) {
|
||||
// 享受8折
|
||||
final_payment = amount * 0.8;
|
||||
} else {
|
||||
// 10. 享受9折
|
||||
final_payment = amount * 0.9;
|
||||
}
|
||||
}
|
||||
// 如果不是VIP,final_payment保持原值,无需else
|
||||
|
||||
cout << final_payment << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Reference in new issue
Block a user