Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
+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.
Reference in new issue
Block a user