Initial commit: C++ courseware

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

No files matched your search

@@ -0,0 +1,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”呢?这需要**两个**关系运算同时成立。要连接多个关系表达式,我们就需要学习下一讲的内容——**逻辑运算符** (`&&`, `||`, `!`)。它们是构建更复杂判断逻辑的桥梁。
@@ -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. **短路求值**:一种优化策略,可以避免不必要的计算。
@@ -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;
```