Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
@@ -0,0 +1,395 @@
|
||||
# 第一章 C++ 程序设计基础
|
||||
|
||||
## 本章内容
|
||||
|
||||
- 1.1 程序设计的目标和流程
|
||||
- 1.2 简单数学运算
|
||||
- 1.3 变量与常量
|
||||
|
||||
## 1.1 程序设计的目标和流程
|
||||
|
||||
### 核心知识
|
||||
|
||||
程序设计的目标,是把现实问题中的处理步骤转化为计算机能够准确执行的指令。一个程序通常要完成三件事:
|
||||
|
||||
1. **接收数据**:获得题目给出的输入。
|
||||
2. **处理数据**:按照公式或规则计算。
|
||||
3. **给出结果**:严格按要求输出答案。
|
||||
|
||||
C++ 属于高级语言。我们编写的源代码不能直接由计算机执行,必须先经过编译。完整流程可以概括为:
|
||||
|
||||
```text
|
||||
分析问题 → 设计算法 → 编写源代码 → 编译与链接 → 运行程序 → 测试结果
|
||||
```
|
||||
|
||||
“编译成功”只表示代码符合语法规则并成功生成程序,不表示计算结果一定正确。
|
||||
|
||||
### 关键语法与规则
|
||||
|
||||
最小的 C++ 程序结构:
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
cout << "Hello, World!" << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
各部分作用:
|
||||
|
||||
| 代码 | 作用 |
|
||||
| --- | --- |
|
||||
| `#include <iostream>` | 引入标准输入输出流库,使程序可以使用 `cin`、`cout` |
|
||||
| `using namespace std;` | 允许直接使用标准命名空间 `std` 中的工具 |
|
||||
| `int main()` | 主函数,也是程序的执行入口 |
|
||||
| `{ ... }` | 标出一个代码块的范围,左右花括号必须配对 |
|
||||
| `cout << ...;` | 向控制台输出数据 |
|
||||
| `return 0;` | 结束 `main`,向系统报告程序正常结束 |
|
||||
|
||||
书写代码时还要注意:
|
||||
|
||||
- C++ 区分大小写,`cout` 与 `Cout` 不是同一个名称。
|
||||
- 代码中的标点应使用英文半角符号。
|
||||
- 大多数语句以英文分号 `;` 结束。
|
||||
- 一个可独立运行的程序必须有且只有一个 `main` 函数。
|
||||
- `#include` 是预处理指令,末尾不写分号。
|
||||
|
||||
注释供程序员阅读,编译器会忽略注释内容:
|
||||
|
||||
```cpp
|
||||
// 单行注释:从 // 开始到本行末尾
|
||||
|
||||
/*
|
||||
块注释:可以跨越多行
|
||||
适合说明一段代码的整体功能
|
||||
*/
|
||||
```
|
||||
|
||||
### 例题
|
||||
|
||||
**题目:** 输出两行文字,第一行输出 `C++ Review`,第二行输出 `Ready!`。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
cout << "C++ Review" << endl;
|
||||
cout << "Ready!" << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**说明:** 程序从 `main` 开始执行。`cout` 负责输出,`endl` 负责换行,每条输出语句都以分号结束。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 把 `cout` 使用的 `<<` 写成 `>>`。
|
||||
- 使用中文分号 `;`、中文引号 `“ ”` 或中文括号。
|
||||
- 漏写分号,或遗漏 `}`,使括号无法配对。
|
||||
- 变量名或工具名拼写错误。
|
||||
- 在 OJ 题目中擅自输出题目没有要求的内容。
|
||||
- 编译器标出的行不一定是真正写错的位置。遇到括号、分号问题时,应同时向前检查。
|
||||
|
||||
## 1.2 简单数学运算
|
||||
|
||||
### 核心知识
|
||||
|
||||
C++ 的基本算术运算符包括:
|
||||
|
||||
| 运算符 | 作用 | 示例 | 结果 |
|
||||
| --- | --- | --- | --- |
|
||||
| `+` | 加法 | `5 + 2` | `7` |
|
||||
| `-` | 减法 | `5 - 2` | `3` |
|
||||
| `*` | 乘法 | `5 * 2` | `10` |
|
||||
| `/` | 除法 | `7 / 2` | `3` |
|
||||
| `%` | 求余 | `7 % 2` | `1` |
|
||||
|
||||
两个整数相除时执行**整数除法**,小数部分直接舍去,不进行四舍五入。只要参与除法的一方是浮点数,才会得到浮点结果。
|
||||
|
||||
### 关键语法与规则
|
||||
|
||||
```cpp
|
||||
cout << 7 / 2; // 3:整数除法
|
||||
cout << 7.0 / 2; // 3.5:浮点除法
|
||||
cout << 14 % 4; // 2:求余
|
||||
cout << (2 + 3) * 4; // 20:括号优先
|
||||
```
|
||||
|
||||
常见优先级从高到低:
|
||||
|
||||
1. 括号 `()`
|
||||
2. 乘、除、取余 `* / %`
|
||||
3. 加、减 `+ -`
|
||||
|
||||
`cout` 中双引号会影响输出含义:
|
||||
|
||||
```cpp
|
||||
cout << "2 + 4"; // 输出文本:2 + 4
|
||||
cout << 2 + 4; // 输出计算结果:6
|
||||
```
|
||||
|
||||
`%` 和整数除法经常配合使用:
|
||||
|
||||
```cpp
|
||||
int n = 479;
|
||||
int ones = n % 10; // 9:提取最右边一位
|
||||
n = n / 10; // 47:去掉最右边一位
|
||||
```
|
||||
|
||||
可以把 `% 10` 记作“个位提取器”,把 `/ 10` 记作“个位削减器”。
|
||||
|
||||
部分数学函数工具需要引入头文件 `<cmath>`:
|
||||
|
||||
```cpp
|
||||
#include <cmath>
|
||||
|
||||
double x = sqrt(81); // 计算根号 81,结果为 9,sqrt(x) 的意义为计算根号x
|
||||
double y = pow(2, 5); // 计算 2 的 5 次方,结果为 32,pow(a, b) 的意义为计算 a 的 b 次方
|
||||
```
|
||||
|
||||
### 例题
|
||||
|
||||
**题目:** 14 个苹果平均分给 4 名同学,输出每人分到的数量和剩余数量,中间用一个空格分隔。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
cout << 14 / 4 << " " << 14 % 4;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```text
|
||||
3 2
|
||||
```
|
||||
|
||||
**说明:** `14 / 4` 得到整数商 3,`14 % 4` 得到余数 2。空格属于文本,因此写成 `" "`。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 误以为 `7 / 2` 会得到 `3.5`。需要写成 `7.0 / 2` 或 `7 / 2.0`。
|
||||
- 对 `double` 使用 `%`。初学阶段把 `%` 理解为整数求余。
|
||||
- 把 `2 ^ 3` 当作 2 的 3 次方。C++ 中 `^` 不是乘方运算。
|
||||
- 忘记括号,导致计算顺序与题意不同。
|
||||
- 把算式放入双引号,程序只会原样输出算式文本。
|
||||
- 输出多个答案时漏掉题目要求的空格或换行。
|
||||
|
||||
## 1.3 变量与常量
|
||||
|
||||
### 核心知识
|
||||
|
||||
变量用于保存输入数据、计算结果和程序运行过程中的中间状态。变量可以理解为内存中带有名称的数据容器。
|
||||
|
||||
使用变量通常包含三个动作:
|
||||
|
||||
1. **定义**:要求说明变量的类型和名称。
|
||||
2. **初始化或赋值**:把数据保存到变量中。
|
||||
3. **读取或更新**:使用变量中的值,或用新值覆盖旧值。
|
||||
|
||||
`=` 是赋值运算符。程序会先计算等号右边,再把结果保存到左边变量中。它与数学中的“相等”含义不同。
|
||||
|
||||
常量用于保存程序运行期间不允许改变的数据。常量使用 `const` 定义,并且必须在定义时初始化。
|
||||
|
||||
### 关键语法与规则
|
||||
|
||||
变量定义、初始化与更新:
|
||||
|
||||
```cpp
|
||||
int a = 10; // 定义并初始化, 语法为:数据类型 + 变量名 = 初始值(其中 = 初始值的部分可以省略)
|
||||
int b, c; // 同时定义两个 int 变量,未赋值
|
||||
b = 3; // 给 b 赋值
|
||||
a = a + 5; // 先计算右边,再把 15 赋给 a
|
||||
a += 2; // 等价于 a = a + 2
|
||||
```
|
||||
|
||||
常见的复合赋值(将运算和赋值合并,一种简便写法):
|
||||
|
||||
| 写法 | 等价写法 |
|
||||
| --- | --- |
|
||||
| `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;` |
|
||||
|
||||
变量命名规则:
|
||||
|
||||
- 只能由字母、数字和下划线组成。
|
||||
- 不能以数字开头。
|
||||
- 不能使用 `int`、`return`、`if` 等 C++ 关键字。
|
||||
- 同一作用域内不能重复定义同名变量。
|
||||
- 建议变量名见名知意,例如 `score`、`totalMinutes`、`radius`。
|
||||
|
||||
常量定义:
|
||||
|
||||
```cpp
|
||||
const double PI = 3.14159;
|
||||
// PI = 3.14; // 错误:常量不能再次赋值
|
||||
```
|
||||
|
||||
### 典型例题
|
||||
|
||||
**题目:** 输入圆的半径,输出圆的周长和面积。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
const double PI = 3.14159;
|
||||
double r;
|
||||
cin >> r;
|
||||
|
||||
double length = 2 * PI * r;
|
||||
double area = PI * r * r;
|
||||
|
||||
cout << length << " " << area;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**说明:** 半径和计算结果可能含小数,因此使用 `double`。圆周率在程序运行期间不应改变,因此定义为常量。
|
||||
|
||||
**变量覆盖示例:书本例1-10 猴子吃桃(P11)。**
|
||||
|
||||
```cpp
|
||||
int peach = 1; // 第四天剩 1 个
|
||||
peach = (peach + 1) * 2; // 倒推第三天
|
||||
peach = (peach + 1) * 2; // 倒推第二天
|
||||
peach = (peach + 1) * 2; // 倒推第一天
|
||||
cout << peach; // 22
|
||||
```
|
||||
|
||||
每次赋值都先使用 `peach` 的旧值完成右侧计算,再用结果覆盖旧值。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 变量没有定义就使用。
|
||||
- 变量未初始化就参与计算,可能得到不可预测的值。
|
||||
- 把 `=` 当作判断相等。赋值写 `a = 5;`,判断相等写 `a == 5`。
|
||||
- 写 `a + 1;` 却以为 `a` 会自动变化。更新变量应写 `a = a + 1;`、`a += 1;` 或 `a++;`。
|
||||
- 常量没有初始化,或在定义后再次赋值。
|
||||
- 变量名以数字开头、包含中文或使用了关键字。
|
||||
|
||||
## 本章练习
|
||||
|
||||
### 一、基础知识
|
||||
|
||||
1. C++ 程序从哪个地方开始执行?
|
||||
|
||||
<br><br>
|
||||
|
||||
2. `#include <iostream>` 的作用是什么?它的末尾是否需要分号?
|
||||
|
||||
<br><br>
|
||||
|
||||
3. 单行注释和块注释分别怎样书写?
|
||||
|
||||
<br><br>
|
||||
|
||||
4. 分别写出加、减、乘、除、求余对应的运算符。
|
||||
|
||||
<br><br>
|
||||
|
||||
5. 计算下列表达式的结果:
|
||||
- `13 / 5`
|
||||
- `13 % 5`
|
||||
- `13.0 / 5`
|
||||
- `(2 + 3) * 4`
|
||||
|
||||
6. 判断下列变量名是否合法,并说明原因:
|
||||
- `score1`
|
||||
- `1score`
|
||||
- `total_score`
|
||||
- `double`
|
||||
- `studentAge`
|
||||
|
||||
7. `=` 在 C++ 中表示什么?`a = a + 1;` 应怎样理解?
|
||||
|
||||
<br><br>
|
||||
|
||||
8. 为什么 `const double PI = 3.14159;` 必须在定义时给出初始值?
|
||||
|
||||
<br><br>
|
||||
|
||||
### 二、代码阅读
|
||||
|
||||
1. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
cout << "3 + 4" << " " << 3 + 4;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
<br><br><br>
|
||||
|
||||
2. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
int a = 5;
|
||||
a = a + 3;
|
||||
a *= 2;
|
||||
cout << a;
|
||||
```
|
||||
|
||||
<br><br><br>
|
||||
|
||||
3. 找出下面代码中的错误并改正:
|
||||
|
||||
```cpp
|
||||
#include <iostream>;
|
||||
using namespace std;
|
||||
|
||||
int Main {
|
||||
cout >> "Hello";
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
4. 写出 `ones` 和 `n` 的最终值:
|
||||
|
||||
```cpp
|
||||
int n = 628;
|
||||
int ones = n % 10;
|
||||
n = n / 10;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### 三、程序设计
|
||||
|
||||
注:**两数运算**要求写上基础的程序结构,而其他的两题只需要从 `int main()` 开始写即可。
|
||||
|
||||
1. **两数运算**
|
||||
|
||||
输入两个整数 `a` 和 `b`,依次输出它们的和、差、积,三个结果之间用一个空格分隔。
|
||||
|
||||
- 样例输入:`8 3`
|
||||
- 样例输出:`11 5 24`
|
||||
|
||||
2. **平均分苹果**
|
||||
|
||||
输入苹果总数 `m` 和学生人数 `n`,输出每人分到的苹果数以及剩余苹果数,中间用一个空格分隔。题目保证 `n > 0`。
|
||||
|
||||
- 样例输入:`17 5`
|
||||
- 样例输出:`3 2`
|
||||
|
||||
3. **圆的周长与面积**
|
||||
|
||||
输入圆的半径 `r`,使用常量 `PI = 3.14159`,输出圆的周长和面积,中间用一个空格分隔。
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,504 @@
|
||||
# 第二章 数据类型与顺序结构程序设计
|
||||
|
||||
## 本章内容
|
||||
|
||||
- 2.1 变量的数据类型
|
||||
- 2.2 变量的输入与输出
|
||||
- 2.3 顺序结构程序设计案例
|
||||
- 2.4 提交评测与错误自查
|
||||
|
||||
## 2.1 变量的数据类型
|
||||
|
||||
### 核心知识
|
||||
|
||||
数据类型决定变量能够保存什么数据、占用多少存储空间,以及参与运算时采用什么规则。基础课程中常用的数据类型包括整数、浮点数、字符和布尔值。
|
||||
|
||||
| 分类 | 类型 | 主要用途 | 示例 |
|
||||
| --- | --- | --- | --- |
|
||||
| 整数 | `short` | 较小范围整数(-128~127) | `short level = 10;` |
|
||||
| 整数 | `int` | 中范围整数,**最常用**(-21亿~21亿) | `int age = 15;` |
|
||||
| 整数 | `long long` | 大范围整数(非常大,万兆以上) | `long long total = 80000000;` |
|
||||
| 浮点数 | `float` | 单精度小数 | `float rate = 0.5;` |
|
||||
| 浮点数 | `double` | 双精度小数,**小数最常用** | `double price = 12.5;` |
|
||||
| 字符 | `char` | 单个字符 | `char grade = 'A';` |
|
||||
| 布尔值 | `bool` | 真或假 | `bool passed = true;` |
|
||||
|
||||
选择类型时要同时考虑数据范围和计算精度。题目可能出现小数时,一般使用 `double`;整数范围可能很大时,需要考虑 `long long`。
|
||||
|
||||
### `char`、转义字符与 ASCII
|
||||
|
||||
`char` 用来保存单个字符,字符值必须使用单引号:
|
||||
|
||||
```cpp
|
||||
char letter = 'A';
|
||||
char digit = '7'; // 数字字符,不是整数 7
|
||||
char op = '*';
|
||||
char blank = ' ';
|
||||
```
|
||||
|
||||
字符串使用双引号。`'A'` 是一个字符,`"A"` 是一个字符串,两者不能混用。
|
||||
|
||||
字符在内存中以整数编码保存。基础题通常使用 ASCII 规律处理英文字母和数字字符:
|
||||
|
||||
| 字符范围 | ASCII 值 |
|
||||
| --- | --- |
|
||||
| `'0'`~`'9'` | 48~57 |
|
||||
| `'A'`~`'Z'` | 65~90 |
|
||||
| `'a'`~`'z'` | 97~122 |
|
||||
|
||||
常用转换:
|
||||
|
||||
```cpp
|
||||
char c = '8';
|
||||
int number = c - '0'; // 数字字符转整数,得到 8
|
||||
|
||||
char upper = 'B';
|
||||
char lower = upper + ('a' - 'A'); // 大写字母转小写字母,得到 'b'
|
||||
|
||||
int code = 65;
|
||||
char letter = (char)code; // 强制转换后得到字符 'A'
|
||||
|
||||
char x = 'A';
|
||||
int ascii = (int)x; // 强制转换后得到整数 65
|
||||
```
|
||||
|
||||
转义序列以反斜杠 `\` 开头:
|
||||
|
||||
| 写法 | 含义 |
|
||||
| --- | --- |
|
||||
| `\n` | 换行 |
|
||||
| `\t` | 水平制表符(Tab键, 一般代表的 4 个空格) |
|
||||
| `\\` | 一个反斜杠 |
|
||||
| `\"` | 一个双引号 |
|
||||
| `\'` | 一个单引号 |
|
||||
|
||||
示例:
|
||||
|
||||
```cpp
|
||||
cout << "小明说:\"what is \\n\"" << '\n';
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```text
|
||||
小明说:"what is \n"
|
||||
```
|
||||
|
||||
### 类型转换
|
||||
|
||||
当表达式中出现不同数据类型时,编译器可能进行自动类型转换。一般而言,整数与浮点数混合运算时,整数会转换为浮点类型:
|
||||
|
||||
```cpp
|
||||
int a = 5;
|
||||
double b = 2.0;
|
||||
double result = a / b; // 2.5
|
||||
```
|
||||
|
||||
把 `double` 转为 `int` 会丢弃小数部分:
|
||||
|
||||
```cpp
|
||||
double value = 3.9;
|
||||
int n = (int)value; // 3,不进行四舍五入
|
||||
```
|
||||
|
||||
如果要转换整个表达式,应把表达式完整括起来:
|
||||
|
||||
```cpp
|
||||
char result = (char)(a + b);
|
||||
```
|
||||
|
||||
### 典型例题
|
||||
|
||||
**题目:** 输入一个大写英文字母,输出对应的小写字母。
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
char upper;
|
||||
cin >> upper;
|
||||
|
||||
char lower = (upper - 'A') + 'a'; // 也可通过加减 32 来实现, 大写转小写需要加 32
|
||||
cout << lower;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**说明:** ASCII 中大写字母和小写字母各自连续排列,而对应大小写字母的差值则一定相同。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 把单个字符写成 `"A"`。`char` 值应使用单引号 `'A'`。
|
||||
- 混淆整数 `7` 与字符 `'7'`。`'7' - '0'` 才得到整数 7。
|
||||
- 让 `int` 保存需要保留小数的计算结果。
|
||||
- 强制类型转换前没有考虑数据范围和精度损失。
|
||||
- 直接假设任何字符都能通过加减 32 转换大小写。该规律只适用于对应的英文字母。
|
||||
- 想输出一个反斜杠时只写一个反斜杠。字符串中应写 `"\\"`。
|
||||
|
||||
## 2.2 变量的输入与输出
|
||||
|
||||
### 核心知识
|
||||
|
||||
`cin`、`cout` 是 C++ 的流式输入输出工具,通过 `<iostream>` 使用。`scanf`、`printf` 是格式化输入输出函数,需要添加 `<cstdio>` 使用。
|
||||
|
||||
输入多个数据时,变量的数量、类型和顺序必须与题意一致。
|
||||
|
||||
输出时不仅要保证答案数值正确,还要严格匹配题目要求的空格、换行、小数位数和文字内容。
|
||||
|
||||
### `cin` 与 `cout`
|
||||
|
||||
```cpp
|
||||
int a, b;
|
||||
cin >> a >> b; // 依次读入两个整数
|
||||
cout << a << " " << b; // 输出两个整数,中间一个空格
|
||||
cout << a + b << '\n'; // 输出计算结果并换行
|
||||
```
|
||||
|
||||
使用规则:
|
||||
|
||||
- `cin` 使用提取运算符 `>>`,把输入保存到变量。
|
||||
- `cout` 使用插入运算符 `<<`,把数据发送到控制台。
|
||||
- `cin >> a >> b;` 会跳过前导的空白字符,输入中的空格、Tab、回车通常都能分隔数据。
|
||||
- `cout << "a+b";` 输出文本 `a+b`;`cout << a + b;` 输出计算结果。
|
||||
- `endl` 和 `'\n'` 都能换行。
|
||||
|
||||
### `scanf` 与 `printf`
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
|
||||
int age;
|
||||
double height;
|
||||
char grade;
|
||||
|
||||
scanf("%d%lf %c", &age, &height, &grade);
|
||||
printf("%d %.2f %c\n", age, height, grade);
|
||||
```
|
||||
|
||||
常用格式说明符:
|
||||
|
||||
| 数据类型 | `scanf` 读取 | `printf` 输出 |
|
||||
| --- | --- | --- |
|
||||
| `int` | `%d` | `%d` |
|
||||
| `long long` | `%lld` | `%lld` |
|
||||
| `float` | `%f` | `%f` |
|
||||
| `double` | `%lf` | `%f` |
|
||||
| `char` | `%c` | `%c` |
|
||||
|
||||
输出小数位数:
|
||||
|
||||
```cpp
|
||||
double value = 3.1415926;
|
||||
printf("%.2f\n", value); // 3.14
|
||||
printf("%.3f\n", value); // 3.142
|
||||
```
|
||||
|
||||
`scanf` 要把数据写入变量,因此变量名前通常要加取地址符 `&`:
|
||||
|
||||
```cpp
|
||||
int n;
|
||||
scanf("%d", &n);
|
||||
```
|
||||
|
||||
格式字符串中的普通字符必须与输入对应:
|
||||
|
||||
```cpp
|
||||
scanf("%d%d", &a, &b); // 可输入:10 20
|
||||
scanf("%d,%d", &a, &b); // 必须输入:10,20
|
||||
```
|
||||
|
||||
`%c` 默认不会跳过空白字符。需要跳过已有的空格或换行时,可在 `%c` 前留一个空格:
|
||||
|
||||
```cpp
|
||||
char op;
|
||||
scanf(" %c", &op);
|
||||
```
|
||||
|
||||
### 典型例题
|
||||
|
||||
**题目:** 输入总水量 `t`(毫升)和人数 `n`。输出每人分到的水量,保留 3 位小数;第二行输出需要的杯子数,每人 2 个杯子。
|
||||
|
||||
```cpp
|
||||
int main() {
|
||||
double t;
|
||||
int n;
|
||||
scanf("%lf%d", &t, &n);
|
||||
|
||||
printf("%.3f\n", t / n);
|
||||
printf("%d\n", n * 2);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**说明:** `scanf` 读取 `double` 使用 `%lf`;`printf` 输出 `double` 使用 `%f`;`%.3f` 表示保留 3 位小数。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 把方向写反:`cin` 使用 `>>`,`cout` 使用 `<<`。
|
||||
- `scanf` 漏写 `&`,导致无法把输入正确保存到变量。
|
||||
- 格式说明符与变量类型不匹配。此问题不只是“精度降低”,还可能导致读取失败或未定义行为。
|
||||
- 混淆 `double` 的格式:`scanf` 读取用 `%lf`,`printf` 输出用 `%f`。
|
||||
- `scanf("%d,%d", ...)` 要求输入中真的出现逗号。
|
||||
- 用 `%c` 读取字符时,意外读入了前一次输入留下的空格或换行。
|
||||
- OJ 输出中多了提示语、单位、标点或空格。
|
||||
|
||||
## 2.3 顺序结构程序设计案例
|
||||
|
||||
### 核心知识
|
||||
|
||||
顺序结构程序按照代码书写顺序逐条执行。基础题通常可以分成“输入、处理、输出”三层:
|
||||
|
||||
```cpp
|
||||
// 1. 输入
|
||||
cin >> ...;
|
||||
|
||||
// 2. 处理
|
||||
// 计算公式、更新变量、转换单位
|
||||
|
||||
// 3. 输出
|
||||
cout << ...;
|
||||
```
|
||||
|
||||
面对程序设计题时,可以使用七步法:
|
||||
|
||||
1. **读懂题目**:明确最终要计算什么。
|
||||
2. **理解输入**:确认数据的数量、类型、顺序和单位。
|
||||
3. **设计逻辑思路**:先写公式或处理步骤。
|
||||
4. **翻译成代码**:定义变量,把思路逐步写成 C++ 语句。
|
||||
5. **处理输出**:安排顺序、空格、换行和精度。
|
||||
6. **编译查错**:先解决语法错误。
|
||||
7. **样例验证**:输入样例并对照输出,再补充边界数据。
|
||||
|
||||
常见解题方法包括:
|
||||
|
||||
- 把复杂计算拆成多个中间结果,用变量保存。
|
||||
- 统一不同单位,再进行计算。
|
||||
- 使用临时变量,防止原数据在赋值时被覆盖。
|
||||
- 在关键位置临时输出中间变量,与手算结果逐步核对。
|
||||
|
||||
交换变量时需要第三个变量中转:
|
||||
|
||||
```cpp
|
||||
int a = 3, b = 4;
|
||||
int temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
```
|
||||
|
||||
### 例题:小鱼的游泳时间
|
||||
|
||||
**题目:** 小鱼从当天 `a` 时 `b` 分游到 `c` 时 `d` 分。输入四个整数,输出游泳时长的小时数和分钟数。本题保证结束时间不早于开始时间。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int a, b, c, d;
|
||||
cin >> a >> b >> c >> d;
|
||||
|
||||
int startMinutes = a * 60 + b;
|
||||
int endMinutes = c * 60 + d;
|
||||
int duration = endMinutes - startMinutes;
|
||||
|
||||
int hours = duration / 60;
|
||||
int minutes = duration % 60;
|
||||
|
||||
cout << hours << " " << minutes;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**思路说明:**
|
||||
|
||||
1. 输入开始时间和结束时间,共 4 个整数。
|
||||
2. 把两个时刻统一换算为分钟。
|
||||
3. 用结束总分钟数减去开始总分钟数。
|
||||
4. 用 `/ 60` 得到小时,用 `% 60` 得到剩余分钟。
|
||||
5. 输入 `12 50 19 10` 时,应输出 `6 20`。
|
||||
|
||||
如果结果错误,可以临时输出中间变量:
|
||||
|
||||
```cpp
|
||||
cout << "start=" << startMinutes << '\n';
|
||||
cout << "end=" << endMinutes << '\n';
|
||||
cout << "duration=" << duration << '\n';
|
||||
```
|
||||
|
||||
提交 OJ 前要删除这些调试输出。
|
||||
|
||||
### 补充案例:按格式反转数字
|
||||
|
||||
输入形如 `123.4` 的固定格式数据,将其输出为 `4.321`。可以把输入看作 4 个字符和一个固定的小数点:
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
|
||||
int main() {
|
||||
char a, b, c, d;
|
||||
scanf("%c%c%c.%c", &a, &b, &c, &d);
|
||||
printf("%c.%c%c%c\n", d, c, b, a);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
这里的 `.` 是格式字符串中的普通字符,因此输入中也必须在对应位置出现小数点。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 把样例数据直接写死,程序无法处理其他合法输入。
|
||||
- 时间差分别计算小时差和分钟差,却没有处理借位。
|
||||
- 交换变量时直接写 `a = b; b = a;`,使原值丢失。
|
||||
- 复杂公式全部写在一行,出错后难以定位。
|
||||
- 只测试样例,不测试整点、临界值、最小值等情况。
|
||||
- 调试输出未删除,导致答案格式不匹配。
|
||||
|
||||
## 2.4 提交评测与错误自查
|
||||
|
||||
### 提交流程
|
||||
|
||||
1. 在本地完成代码并成功编译。
|
||||
2. 输入题目样例,确认输出内容和格式一致。
|
||||
3. 把完整源代码提交到 OJ。
|
||||
4. 根据评测结果定位问题,修改后重新测试和提交。
|
||||
|
||||
OJ 只检查程序输出的字符序列是否符合要求。不要擅自添加输入提示、答案说明或单位。
|
||||
|
||||
### 常见评测结果
|
||||
|
||||
| 结果 | 含义 | 优先检查 |
|
||||
| --- | --- | --- |
|
||||
| **AC(Accepted)** | 通过全部测试数据 | 程序已通过本题评测 |
|
||||
| **CE(Compile Error)** | 编译错误 | 分号、括号、变量名、头文件、中文标点 |
|
||||
| **WA(Wrong Answer)** | 答案错误 | 公式、条件、类型、边界情况、输出格式 |
|
||||
| RE(Runtime Error) | 运行时错误 | 除数为 0、非法访问、错误输入函数用法 |
|
||||
| TLE(Time Limit Exceeded) | 超出时间限制 | 算法效率、循环终止条件 |
|
||||
|
||||
### 错误自查顺序
|
||||
|
||||
#### 出现 CE
|
||||
|
||||
1. 查看编译器给出的第一条错误信息和行号。
|
||||
2. 检查该行以及前一行是否漏写分号。
|
||||
3. 检查 `()`、`{}`、引号是否成对。
|
||||
4. 检查变量是否先定义后使用,名称是否拼写一致。
|
||||
5. 检查是否误用了中文标点或缺少头文件。
|
||||
|
||||
#### 出现 WA
|
||||
|
||||
1. 先检查输出格式:空格、换行、小数位数、文字大小写。
|
||||
2. 用草稿纸手算样例和一组自选数据。
|
||||
3. 分步输出中间变量,找出第一个与手算不一致的位置。
|
||||
4. 检查整数除法、数据类型和运算优先级。
|
||||
5. 检查最小值、最大值、临界值和特殊情况。
|
||||
|
||||
#### 出现 RE(目前较少遇见)
|
||||
|
||||
1. 检查除数是否可能为 0。
|
||||
2. 检查 `scanf` 的格式说明符和 `&`。
|
||||
|
||||
## 本章练习
|
||||
|
||||
### 一、基础知识
|
||||
|
||||
1. 为下列数据选择合适的类型:学生人数、商品价格、考试等级字符、条件真假、较大的整数总数。
|
||||
|
||||
<br><br>
|
||||
|
||||
2. 说明字符 `'7'` 与整数 `7` 的区别。
|
||||
|
||||
<br><br>
|
||||
|
||||
3. 写出 `'0'`、`'A'`、`'a'` 的 ASCII 值。
|
||||
|
||||
<br><br>
|
||||
|
||||
4. 写出以下转换表达式:
|
||||
- 数字字符 `ch` 转为对应的整数数字。
|
||||
- 大写英文字母 `upper` 转为对应的小写字母。
|
||||
- 整数 `code` 强制转换为字符。
|
||||
|
||||
5. 写出下列转义序列的作用:`\n`、`\t`、`\\`、`\"`。
|
||||
|
||||
<br><br>
|
||||
|
||||
7. `scanf` 读取 `int`、`double`、`char` 时分别使用什么格式说明符?
|
||||
|
||||
<br><br>
|
||||
|
||||
8. `printf` 输出 `double` 并保留两位小数时,格式说明符应怎样写?
|
||||
|
||||
<br><br>
|
||||
|
||||
9. `scanf` 中为什么通常要在变量名前加 `&`?
|
||||
|
||||
<br><br>
|
||||
|
||||
10. 分别说明 AC、CE、WA 的含义。
|
||||
|
||||
<br><br>
|
||||
|
||||
### 二、代码阅读与改错
|
||||
|
||||
1. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
char c = '6';
|
||||
int n = c - '0';
|
||||
cout << n + 4;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
2. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
char upper = 'C';
|
||||
char lower = upper + ('a' - 'A');
|
||||
cout << lower;
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
<br>
|
||||
|
||||
3. 找出格式说明符的错误并改正:
|
||||
|
||||
```cpp
|
||||
int age;
|
||||
double height;
|
||||
scanf("%lf%d", &age, &height);
|
||||
printf("%d %.2d\n", age, height);
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
4. 找出变量交换失败的原因并改正:
|
||||
|
||||
```cpp
|
||||
int a = 3, b = 8;
|
||||
a = b;
|
||||
b = a;
|
||||
cout << a << " " << b;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### 三、程序设计
|
||||
|
||||
1. **字符与 ASCII**
|
||||
|
||||
输入一个字符,输出该字符以及它对应的 ASCII 值,中间用一个空格分隔。
|
||||
|
||||
- 样例输入:`A`
|
||||
- 样例输出:`A 65`
|
||||
|
||||
2. **数字字符转整数**
|
||||
|
||||
输入一个 `'0'`~`'9'` 的数字字符,将它转换成整数后加 5,并输出结果。
|
||||
|
||||
- 样例输入:`7`
|
||||
- 样例输出:`12`
|
||||
|
||||
6. **格式化平均值**
|
||||
|
||||
输入三个 `double` 数据,输出它们的平均值,结果需要严格保留 3 位小数。
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,628 @@
|
||||
# 第三章 关系、逻辑与分支结构
|
||||
|
||||
## 本章内容
|
||||
|
||||
- 3.1 关系表达式与逻辑表达式
|
||||
- 3.2 分支语句
|
||||
- 3.3 分支嵌套
|
||||
- 3.4 分支程序设计案例
|
||||
|
||||
## 3.1 关系表达式与逻辑表达式
|
||||
|
||||
### 核心知识
|
||||
|
||||
关系运算用于比较两个值,结果是 `bool` 类型,即 `true` 或 `false`。而逻辑运算符可以把多个真假条件组合成更复杂的判断。
|
||||
|
||||
C++ 在需要判断真假的位置,会把数值 `0` 视为假,把非零值视为真。`cout` 默认把 `true` 输出为 `1`,把 `false` 输出为 `0`。
|
||||
|
||||
### 关系运算符
|
||||
|
||||
| 运算符 | 含义 | 示例 |
|
||||
| --- | --- | --- |
|
||||
| `==` | 等于 | `score == 100` |
|
||||
| `!=` | 不等于 | `x != 0` |
|
||||
| `>` | 大于 | `a > b` |
|
||||
| `<` | 小于 | `a < b` |
|
||||
| `>=` | 大于等于 | `age >= 18` |
|
||||
| `<=` | 小于等于 | `score <= 60` |
|
||||
|
||||
关系表达式示例:
|
||||
|
||||
```cpp
|
||||
bool result1 = (10 > 5); // true
|
||||
bool result2 = (3 == 4); // false
|
||||
bool result3 = (7 != 0); // true
|
||||
```
|
||||
|
||||
### 逻辑运算符
|
||||
|
||||
| 表达式 | 含义 | 何时为真 |
|
||||
| --- | --- | --- |
|
||||
| `A && B` | A 并且 B | A、B 都为真 |
|
||||
| `A || B` | A 或者 B | A、B 至少一个为真 |
|
||||
| `!A` | 不是 A | A 为假 |
|
||||
|
||||
自然语言与 C++ 表达式对照:
|
||||
|
||||
```cpp
|
||||
// x 在闭区间 [10, 20] 内
|
||||
(x >= 10) && (x <= 20)
|
||||
|
||||
// x 小于 0 或大于 100
|
||||
(x < 0) || (x > 100)
|
||||
|
||||
// x 是 3 的倍数,但不是偶数
|
||||
(x % 3 == 0) && (x % 2 != 0)
|
||||
|
||||
// x 不等于 10
|
||||
!(x == 10) // 或者 x != 10
|
||||
```
|
||||
|
||||
构建逻辑表达式时,可以按三个步骤完成:
|
||||
|
||||
1. **拆解条件**:把长规则拆成独立的小判断。
|
||||
2. **寻找连接词**:“并且”对应 `&&`,“或者”对应 `||`,“不”对应 `!`。
|
||||
3. **组合表达式**:使用括号明确每一组条件之间的关系。
|
||||
|
||||
### 运算优先级
|
||||
|
||||
常用优先级从高到低可概括为(**非算关与或**):
|
||||
|
||||
```text
|
||||
括号 → 逻辑非 ! → 算术运算 → 关系运算 → && → ||
|
||||
```
|
||||
|
||||
对于一些复杂表达式应主动使用括号,不要只依赖优先级记忆,例如:
|
||||
|
||||
```cpp
|
||||
(math == 100 || english == 100) && homeworkFinished
|
||||
```
|
||||
|
||||
### 短路求值
|
||||
|
||||
对于 `A && B`:
|
||||
|
||||
- 如果 A 为假,整个表达式一定为假,B 不再执行。
|
||||
|
||||
对于 `A || B`:
|
||||
|
||||
- 如果 A 为真,整个表达式一定为真,B 不再执行。
|
||||
|
||||
```cpp
|
||||
int x = 0;
|
||||
int y = 10;
|
||||
|
||||
bool a = (x != 0) && (100 / x > 2);
|
||||
// 左侧为 false,右侧不执行,避免除以 0
|
||||
|
||||
bool b = (y > 0) || (++y > 20);
|
||||
// 左侧为 true,右侧不执行,y 仍为 10
|
||||
```
|
||||
|
||||
短路既能减少不必要的计算,也能保护右侧表达式不在非法条件下执行。
|
||||
|
||||
### 典型例题:闰年表达式
|
||||
|
||||
闰年规则为:年份能被 4 整除但不能被 100 整除,或者能被 400 整除。
|
||||
|
||||
拆解:
|
||||
|
||||
- A:`year % 4 == 0`
|
||||
- B:`year % 100 != 0`
|
||||
- C:`year % 400 == 0`
|
||||
|
||||
组合:
|
||||
|
||||
```cpp
|
||||
bool leap = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
|
||||
```
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 判断相等时写成 `=`。`=` 是赋值,`==` 才是比较。
|
||||
- 写成数学连写 `5 < x < 10`。正确写法是 `x > 5 && x < 10`。
|
||||
- 把逻辑与、逻辑或写成 `&`、`|`。应使用 `&&`、`||`。
|
||||
- 区间题漏掉端点的等号。
|
||||
- 复杂条件没有括号,导致实际的计算优先级与题意不同。
|
||||
- 在逻辑表达式右侧使用 `x++` 等有副作用的操作,却忽略短路可能导致它不执行。
|
||||
|
||||
## 3.2 分支语句
|
||||
|
||||
### 核心知识
|
||||
|
||||
分支结构让程序根据条件选择不同的执行路径:
|
||||
|
||||
- `if`:只关心条件成立时需要做什么。
|
||||
- `if-else`:处理二选一。
|
||||
- `if-else if-else`:处理多个互斥选项,只执行首次满足的分支。
|
||||
- 多个独立 `if`:每个条件分别判断,可能执行多个分支。
|
||||
- `switch`:处理同一个整型或字符型表达式的多路等值选择。
|
||||
|
||||
### 单分支和双分支
|
||||
|
||||
```cpp
|
||||
if (condition) {
|
||||
// condition 为 true 时执行
|
||||
}
|
||||
```
|
||||
|
||||
```cpp
|
||||
if (condition) {
|
||||
// 条件成立时执行
|
||||
} else {
|
||||
// 条件不成立时执行
|
||||
}
|
||||
```
|
||||
|
||||
奇偶判断:
|
||||
|
||||
```cpp
|
||||
if (number % 2 == 0) {
|
||||
cout << "偶数";
|
||||
} else {
|
||||
cout << "奇数";
|
||||
}
|
||||
```
|
||||
|
||||
### 多分支
|
||||
|
||||
```cpp
|
||||
if (condition1) {
|
||||
// 第一种情况
|
||||
} else if (condition2) {
|
||||
// 第一种情况不成立,第二种情况成立
|
||||
} else {
|
||||
// 以上条件都不成立
|
||||
}
|
||||
```
|
||||
|
||||
多分支按照从上到下的顺序判断。一旦某个条件为真,程序执行对应代码块,然后跳过整条分支链。因此,条件书写顺序会影响结果。
|
||||
|
||||
例如对于成绩分级的实例,应首先判断更高的分数:
|
||||
|
||||
```cpp
|
||||
if (score >= 90) {
|
||||
cout << "A";
|
||||
} else if (score >= 80) {
|
||||
cout << "B";
|
||||
} else if (score >= 60) {
|
||||
cout << "C";
|
||||
} else {
|
||||
cout << "D";
|
||||
}
|
||||
```
|
||||
|
||||
而且对于多分支而言,后面的条件隐含了前面条件不成立。例如在执行 `score >= 80` 的分支时,已经知道 `score < 90`。
|
||||
|
||||
### 独立 `if` 与 `else if`
|
||||
|
||||
多个独立 `if` 属于“多选多”:
|
||||
|
||||
```cpp
|
||||
if (x % 2 == 0) {
|
||||
cout << "even ";
|
||||
}
|
||||
if (x % 3 == 0) {
|
||||
cout << "multiple of 3";
|
||||
}
|
||||
```
|
||||
|
||||
当 `x` 为 6 时,两个条件都成立,两段代码都会执行。
|
||||
|
||||
`if-else if` 属于“多选一”:前面的分支一旦命中,后面的分支不再判断。
|
||||
|
||||
### `switch` 多路选择
|
||||
|
||||
`switch` 适合对同一个表达式进行多个等值匹配:
|
||||
|
||||
```cpp
|
||||
switch (expression) {
|
||||
case constant1:
|
||||
// expression 等于 constant1
|
||||
break;
|
||||
case constant2:
|
||||
// expression 等于 constant2
|
||||
break;
|
||||
default:
|
||||
// 没有任何 case 匹配
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- `switch` 后的 `expression` 表达式应为整型、字符型的值。
|
||||
- `case` 后的 `constant` 所匹配的值必须是常量,不能写范围条件,不能写变量。
|
||||
- `break` 会立即跳出 `switch`。
|
||||
- `default` 是可选的保底分支,作用类似多分支最后的 `else`。
|
||||
- 缺少 `break` 时,程序会从匹配位置继续向下执行直到遇到 `break` 为止,这种情况称为** `case` 穿透**。
|
||||
|
||||
在一些特殊情况,多个 `case` 可以有意使用穿透来共用一段逻辑:
|
||||
|
||||
```cpp
|
||||
switch (letter) {
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
cout << "元音";
|
||||
break;
|
||||
default:
|
||||
cout << "非元音";
|
||||
break;
|
||||
}
|
||||
```
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 在 `if` 条件后误写分号:
|
||||
|
||||
```cpp
|
||||
if (x > 0); { // 错误:分号提前结束了 if
|
||||
cout << x;
|
||||
}
|
||||
```
|
||||
|
||||
- 省略花括号后添加第二条语句,误以为两条语句都受 `if` 控制。
|
||||
- 把多选一写成多个独立 `if`,造成多个分支同时输出。
|
||||
- 把允许多个结果的情况写成 `else if`,导致后续条件被跳过。
|
||||
- 多分支先写宽松条件,导致严格条件永远没有机会命中。
|
||||
- 用 `switch` 处理 `score >= 60` 等范围条件。
|
||||
- `case` 后写变量、范围或重复的常量值。
|
||||
- 漏写 `break`,造成意外穿透。
|
||||
|
||||
## 3.3 分支嵌套
|
||||
|
||||
### 核心知识
|
||||
|
||||
分支嵌套,是在一个 `if`、`else if` 或 `else` 的代码块内部再放入一个完整的分支结构。
|
||||
|
||||
嵌套适合“先判断大前提,再处理细分情况”的问题:
|
||||
|
||||
- 外层分支确定主要类别或进入资格。
|
||||
- 内层分支只在外层条件成立后继续判断。
|
||||
- 如果外层条件不成立,内层条件不会执行。
|
||||
|
||||
### 语法与执行流程
|
||||
|
||||
```cpp
|
||||
if (外层条件) {
|
||||
if (内层条件) {
|
||||
// 外层条件和内层条件都成立
|
||||
} else {
|
||||
// 外层条件成立,但内层条件不成立
|
||||
}
|
||||
} else {
|
||||
// 外层条件不成立
|
||||
}
|
||||
```
|
||||
|
||||
执行过程:
|
||||
|
||||
1. 先判断外层条件。
|
||||
2. 外层条件为假时,跳过整个外层代码块。
|
||||
3. 外层条件为真时,进入代码块,再判断内层条件。
|
||||
4. 内层分支执行完成后,程序继续执行嵌套结构后面的代码。
|
||||
|
||||
### 典型例题:会员折扣
|
||||
|
||||
商场规则如下:
|
||||
|
||||
- 非会员按原价结算。
|
||||
- 会员消费满 500 元打 8 折。
|
||||
- 会员消费不足 500 元打 9 折。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
double amount;
|
||||
bool isMember;
|
||||
cin >> amount >> isMember;
|
||||
|
||||
double payment = amount;
|
||||
|
||||
if (isMember) {
|
||||
if (amount >= 500) {
|
||||
payment = amount * 0.8;
|
||||
} else {
|
||||
payment = amount * 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
cout << payment;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
**说明:** 外层先判断会员资格,只有会员才进入内层判断消费金额。非会员不进入内层,`payment` 保持原价。
|
||||
|
||||
### 常见错误
|
||||
|
||||
- 缩进混乱,无法看清 `else` 与哪个 `if` 配对。
|
||||
- 外层条件不成立时仍然期待内层判断执行。
|
||||
- 把所有条件都塞进多层嵌套,使代码难以阅读。能用清晰逻辑表达式解决时,不必强行嵌套。
|
||||
- 忘记为各层代码块补齐花括号。
|
||||
- 在不同层级重复或遗漏条件,导致某些情况没有处理。
|
||||
|
||||
## 3.4 分支程序设计案例
|
||||
|
||||
解决分支题时,可以采用四步流程:
|
||||
|
||||
1. **找到分岔点**:哪些条件会改变程序执行路径?
|
||||
2. **写出条件表达式**:把自然语言准确翻译为关系或逻辑表达式。
|
||||
3. **选择分支结构**:单选、二选一、多选一、多选多、嵌套或 `switch`。
|
||||
4. **实现各分支代码**:在每个分支写入对应处理代码。
|
||||
|
||||
### 案例一:BMI 分类
|
||||
|
||||
输入体重 `mass`(kg)和身高 `height`(m),计算 BMI。小于 18.5 输出 `Underweight`;小于 24 输出 `Normal`;否则输出 `Overweight`。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
double mass, height;
|
||||
cin >> mass >> height;
|
||||
|
||||
double bmi = mass / (height * height);
|
||||
|
||||
if (bmi < 18.5) {
|
||||
cout << "Underweight";
|
||||
} else if (bmi < 24) {
|
||||
cout << "Normal";
|
||||
} else {
|
||||
cout << "Overweight";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
第二个分支隐含了第一个条件不成立,即 `bmi >= 18.5`,所以只需继续判断 `bmi < 24`。
|
||||
|
||||
### 案例二:闰年判断
|
||||
|
||||
输入年份。如果是闰年,输出该年份;否则输出 `No`。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int year;
|
||||
cin >> year;
|
||||
|
||||
bool leap = ((year % 4 == 0) && (year % 100 != 0))
|
||||
|| (year % 400 == 0);
|
||||
|
||||
if (leap) {
|
||||
cout << year;
|
||||
} else {
|
||||
cout << "No";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
本题先用关系和逻辑运算构建一个完整条件,再用 `if-else` 根据真假输出。
|
||||
|
||||
### 案例三:简易计算器
|
||||
|
||||
输入形如 `7 * 2` 的表达式,根据运算符完成计算。
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
double a, b;
|
||||
char op;
|
||||
cin >> a >> op >> b;
|
||||
|
||||
switch (op) {
|
||||
case '+':
|
||||
cout << a + b;
|
||||
break;
|
||||
case '-':
|
||||
cout << a - b;
|
||||
break;
|
||||
case '*':
|
||||
cout << a * b;
|
||||
break;
|
||||
case '/':
|
||||
if (b == 0) {
|
||||
cout << "Error";
|
||||
} else {
|
||||
cout << a / b;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cout << "Unknown operator";
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
`switch` 负责对字符 `op` 做等值匹配;除法分支中再用嵌套 `if` 检查除数是否为 0。
|
||||
|
||||
## 本章练习
|
||||
|
||||
### 一、表达式练习
|
||||
|
||||
用 C++ 表达式表示下列条件:
|
||||
|
||||
1. `x` 大于等于 10 且小于等于 20。
|
||||
|
||||
<br>
|
||||
|
||||
2. `x` 小于 0 或大于 100。
|
||||
|
||||
<br>
|
||||
|
||||
3. `n` 是 5 的倍数。
|
||||
|
||||
<br>
|
||||
|
||||
4. `n` 能被 3 整除,但不能被 2 整除。
|
||||
|
||||
<br>
|
||||
|
||||
5. 字符 `ch` 是大写英文字母。
|
||||
|
||||
<br>
|
||||
|
||||
6. 年龄 `age` 不在 7~15 岁的范围内。
|
||||
|
||||
<br>
|
||||
|
||||
7. 数学或英语至少有一门达到 90 分,并且作业已经完成。变量分别为 `math`、`english`、`homeworkFinished`。
|
||||
|
||||
<br>
|
||||
|
||||
9. `a`、`b`、`c` 三个条件中至少有两个为真。
|
||||
|
||||
<br>
|
||||
|
||||
### 二、代码阅读
|
||||
|
||||
1. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
int x = 8;
|
||||
if (x > 5) {
|
||||
cout << "A";
|
||||
}
|
||||
if (x % 2 == 0) {
|
||||
cout << "B";
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
2. 写出程序的输出结果,并说明原因:
|
||||
|
||||
```cpp
|
||||
int score = 85;
|
||||
if (score >= 60) {
|
||||
cout << "及格";
|
||||
} else if (score >= 80) {
|
||||
cout << "良好";
|
||||
} else if (score >= 90) {
|
||||
cout << "优秀";
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
3. 写出 `y` 的最终值:
|
||||
|
||||
```cpp
|
||||
int x = 5;
|
||||
int y = 10;
|
||||
bool result = (x > 1) || (++y > 20);
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
4. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
int n = 2;
|
||||
switch (n) {
|
||||
case 1:
|
||||
cout << "A";
|
||||
case 2:
|
||||
cout << "B";
|
||||
case 3:
|
||||
cout << "C";
|
||||
break;
|
||||
default:
|
||||
cout << "D";
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
5. 写出程序的输出结果:
|
||||
|
||||
```cpp
|
||||
bool loggedIn = true;
|
||||
bool isAdmin = false;
|
||||
|
||||
if (loggedIn) {
|
||||
if (isAdmin) {
|
||||
cout << "管理员";
|
||||
} else {
|
||||
cout << "普通用户";
|
||||
}
|
||||
} else {
|
||||
cout << "未登录";
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
6. 判断表达式 `5 < x < 10` 能否正确表示 `x` 在 5 和 10 之间,并说明计算过程。
|
||||
|
||||
<br><br>
|
||||
|
||||
### 三、程序改错
|
||||
|
||||
1. 改正下面的判断语句:
|
||||
|
||||
```cpp
|
||||
if (score = 100); {
|
||||
cout << "Full marks";
|
||||
}
|
||||
```
|
||||
|
||||
2. 下面的程序想判断 `x` 是否在闭区间 [10, 20] 内,请改正:
|
||||
|
||||
```cpp
|
||||
if (10 <= x <= 20) {
|
||||
cout << "Yes";
|
||||
}
|
||||
```
|
||||
|
||||
3. 下面的成绩分级程序可以正确的区分等级吗?
|
||||
|
||||
```cpp
|
||||
if (score >= 60) {
|
||||
cout << "C";
|
||||
} else if (score >= 80) {
|
||||
cout << "B";
|
||||
} else if (score >= 90) {
|
||||
cout << "A";
|
||||
} else {
|
||||
cout << "D";
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### 四、程序设计
|
||||
|
||||
1. **奇偶判断**
|
||||
|
||||
输入一个整数,偶数输出 `Even`,奇数输出 `Odd`。
|
||||
|
||||
2. **景点门票**
|
||||
|
||||
某景点全价票 50 元。年龄不超过 6 岁或不低于 60 岁时票价为 25 元,其余情况为 50 元。输入年龄,输出票价。
|
||||
|
||||
- 样例输入:`65`
|
||||
- 样例输出:`25`
|
||||
|
||||
3. **三个数的最大值**
|
||||
|
||||
输入三个整数,使用分支语句输出其中的最大值。
|
||||
|
||||
- 样例输入:`6 5 2`
|
||||
- 样例输出:`6`
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,230 @@
|
||||
# C++ 编程讲义 — 初识C++
|
||||
|
||||
工欲善其事,必先利其器。
|
||||
|
||||
编程本质上是我们通过计算机向机器下达精确指令的过程。因此,在正式编写第一行代码之前,我们必须先熟练掌握并使用最核心的工具——电脑的基本操作与 Windows 操作系统。对于初次接触计算机的同学,我们需要从最基础的物理设备开始学习。
|
||||
|
||||
---
|
||||
|
||||
## 第一部分:计算机基础设备操作
|
||||
|
||||
### 一、鼠标的基本操作
|
||||
|
||||
鼠标是我们在图形界面中向计算机发送位置与选择指令的设备。
|
||||
|
||||
* **左键单击**:用食指按一下鼠标左键并立即松开。用于选定目标(例如选中一段代码或定位光标)。
|
||||
* **左键双击**:快速、连续地按两次鼠标左键。通常用于打开软件或选中一整个单词。
|
||||
* **右键单击**:用中指按一下鼠标右键。用于唤出快捷菜单,可以在其中找到复制、粘贴等功能。
|
||||
* **拖拽**:按住左键不放,移动鼠标到目标位置后再松开。用于移动窗口或选中多行文本。
|
||||
|
||||
### 二、熟悉键盘按键
|
||||
|
||||
键盘是编写代码时最重要的输入设备。标准键盘一般包括26个英文字母键、10个数字键、12个功能键(F1~F12)、方向键以及其他的一些功能键。
|
||||
|
||||
所有按键在物理布局上主要分为5个区:
|
||||
|
||||
1. **主键盘区**:最大的一块区域,包含字母、数字和常用标点符号,是我们书写代码的核心区域。
|
||||
2. **功能键区(F1~F12)**:位于键盘最上方,在不同的软件中有不同的快捷功能。
|
||||
3. **编辑/控制键区**:包含方向键、删除键(Delete)等,用于在代码中移动光标和修改文本。
|
||||
4. **小键盘区**:位于最右侧,主要用于快速输入纯数字。
|
||||
5. **键盘指示灯**:提示当前键盘的状态(如大小写锁定、数字键盘锁定等)。
|
||||
|
||||
### **编程必须掌握的按键指令:**
|
||||
|
||||
* **Shift 键(上档键)**:用于切换中英文标点符号,或输入按键上半部分的符号(例如按住 Shift 再按数字 9,可以打出左括号 `(` )。
|
||||
* **Enter 键(回车键)**:在代码中用于换行,使指令结构清晰。
|
||||
* **Backspace 键(退格键)**:用于删除光标前面的字符,是修改代码错误的常用键。
|
||||
|
||||
---
|
||||
|
||||
## 第二部分:什么是程序与计算机语言?
|
||||
|
||||
大家目前可能对软件中复杂的程序代码感到难以理解,但是,大家了解人类生活中的程序吗?有什么程序是大家在日常生活中经历过的呢?
|
||||
|
||||
**例如:开学典礼的程序**
|
||||
主持人会宣布,今天典礼的程序如下:
|
||||
|
||||
* 第一项:升国旗;
|
||||
* 第二项:领导介绍;
|
||||
* 第三项:校长致辞;
|
||||
* 第四项:教师代表发言;
|
||||
* 第五项:学生代表发言。
|
||||
|
||||
这其实就是人类社会的程序。映射到计算机科学中,**计算机的程序被定义为:为了得到某种结果,通过计算机语言表达的指令序列。** 计算机通过严格执行你下达的指令,最终得出预期的结果。
|
||||
|
||||
**假如我们要编写一个让计算机“把大象塞进冰箱”的程序,相当于依次下达以下指令:**
|
||||
|
||||
1. 打开冰箱门;
|
||||
2. 把大象塞进冰箱;
|
||||
3. 关上冰箱门。
|
||||
|
||||
### 计算机语言的演变与分类
|
||||
|
||||
为了把上述指令传达给计算机,我们需要使用计算机语言。计算机语言主要分为三种:
|
||||
|
||||
1. **机器语言(二进制语言)**:由 `0` 和 `1` 组成,这是计算机底层唯一能直接听懂的语言,但人类极难阅读和编写。
|
||||
2. **汇编语言**:使用一些简短的英文字母代替二进制代码,比机器语言稍易读,但依然非常晦涩。
|
||||
3. **高级语言(接近英语/自然语言)**:使用人类容易理解的英文字母、单词和数学符号编写。
|
||||
|
||||
我们即将学习的 **C++ 课程就属于高级语言**。它的本质是由一套特定的英文单词和符号组成的指令集合。然而,计算机底层只能听懂二进制,这就意味着,**必须要将高级语言“翻译”成机器语言,计算机才能执行。**
|
||||
|
||||
---
|
||||
|
||||
## 第三部分:C++ 开发工具 (Dev-C++) 与执行过程
|
||||
|
||||
那我们应该在什么地方、如何去书写这些高级语言呢?这就需要用到专业的集成开发环境(IDE)。
|
||||
|
||||
### 一、初识 Dev-C++
|
||||
|
||||
对于初学者,我们使用 **Dev-C++**。这是一款专门用于书写和运行 C/C++ 高级语言的工具。它提供了一个干净的文本编辑区,并且内置了代码高亮等便捷功能,极大地规范和方便了我们的书写。
|
||||
|
||||
### 二、程序的编译(翻译)与报错机制
|
||||
|
||||
当我们在 Dev-C++ 中书写好高级语言代码后,此时代码还只是一堆英文字符,系统在等待着“翻译官”进行翻译。
|
||||
**这个“翻译”的过程,在计算机科学中被称为“编译 ”。**
|
||||
|
||||
* **严格的语法**:翻译官只能翻译它看得懂的、符合严格规则的代码。如果代码存在拼写错误,或者不符合语法要求,翻译官就会看不懂并拒绝工作。
|
||||
* **编译报错(出现红色的 ×)**:如果下方窗口出现红色的 `×` 或错误提示,说明代码有错误,翻译失败。**只有在代码完全无误,翻译官顺利翻译后,程序才能被执行。**
|
||||
* **标点符号规范**:因为 C++ 是一门基于英文环境诞生的语言,它的指令**无法识别中文标点符号**。如果误用了中文的逗号(,)或分号(;),就等同于你自创了一个不存在的单词,翻译官会直接报错。编写代码时,必须确保输入法处于**英文半角**状态。
|
||||
|
||||
### 三、编译并运行(快捷键 F11)
|
||||
|
||||
当确保代码书写完毕且无误后,我们需要让计算机去执行命令。
|
||||
在 Dev-C++ 中,**按下键盘上的 `F11` 键,即可一键开始“编译并运行”程序。** 软件会自动先将代码翻译为机器语言,紧接着让计算机执行它。
|
||||
|
||||
### 四、控制台(黑框框)
|
||||
|
||||
按下 `F11` 并且编译成功后,屏幕上会弹出一个黑色的独立窗口。这个窗口被称为**控制台**。
|
||||
控制台的作用是**展示程序的最终运行结果**,或者在程序需要用户输入数据时,**与程序进行交互**。当控制台弹出并显示出预期的结果时,就意味着你的指令被计算机成功执行了。
|
||||
|
||||
---
|
||||
|
||||
## 第四部分:初识 C++ —— 第一个程序 Hello World
|
||||
|
||||
了解了工具后,我们将正式开始编写全人类学习编程时的第一个经典程序:向世界问好。
|
||||
|
||||
### 一、代码示例
|
||||
|
||||
在 Dev-C++ 的代码编辑区中,输入以下代码:
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
cout << "Hello, World!" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 二、代码解析
|
||||
|
||||
这段看似复杂的英文,其实每一行都有其含义:
|
||||
|
||||
* **`#include <iostream>` —— 引入输入输出流库**
|
||||
* **含义**:告诉计算机“我需要使用标准的输入和输出工具”。如果没有这一句指令,计算机就无法理解后续代码中用于在屏幕上显示文字的命令。
|
||||
* 就像做披萨前,要先准备好烤箱和工具,没有烤箱肯定无法制作披萨。
|
||||
* 如果没有这一句,电脑就不知道什么是 `cout`,没有用来输出文字的工具,自然就没法输出文字。
|
||||
|
||||
|
||||
|
||||
* **`using namespace std;` —— 使用标准命名空间**
|
||||
|
||||
* **含义**:告诉计算机“本程序默认使用名为 `std` 的标准工具库”。
|
||||
* 比如:A 工具箱和 B 工具箱都有个锤子,你就要先说清楚是哪个工具箱的,不然计算机就会搞混。
|
||||
* `std` 就像 工具箱,`cout` 就像锤子。
|
||||
* 写了这一句,相当于告诉电脑:“我默认要锤子的时候都用的是 `std` 这个工具箱。”,我们以后要用的所有的工具基本都是在`std`这个工具箱里的。
|
||||
|
||||
|
||||
|
||||
* **`int main() {` —— 主程序入口**
|
||||
|
||||
* **含义**:这是所有 C++ 程序的起点。程序执行时,必定从 `main` 函数后方的大括号 `{` 开始,到对应的大括号 `}` 结束。一个完整的 C++ 程序必须有且仅有一个 `main` 。`int` 是单词 **integer** 的缩写,意思是“整数”,规定这个函数最终执行完毕后,必须向计算机汇报一个整数作为结果。
|
||||
* 好比一个“主任务清单”,电脑会从这里开始做事情。
|
||||
|
||||
|
||||
|
||||
* **`cout << "Hello, World!";` —— 屏幕输出指令**
|
||||
|
||||
* `cout`:用于输出数据的工具,相当于一个“喇叭”,把数据告诉计算机让它来输出。
|
||||
* `<<`:像传送带,把右边的东西送到左边。
|
||||
* **`"Hello, World!"`**:被英文双引号包裹的内容,即我们要原样显示在屏幕上的具体文字数据。
|
||||
* **整句话的意思**:把 "Hello, World!" 交给输出系统,让它把这句话输出在控制台上。
|
||||
|
||||
* *注意:这一行的末尾必须以英文分号 `;` 结束,C++ 里 `;` 代表一条指令的执行完毕。*
|
||||
|
||||
|
||||
* **`return 0;` —— 正常结束程序**
|
||||
|
||||
* **含义**:返回一个数字 `0` 给系统。`0` 表示一切正常。
|
||||
* 好比告诉老师:“作业完成了,没有出错。”
|
||||
|
||||
|
||||
* **`}` —— 程序结束**
|
||||
|
||||
* **含义**:与前文的 `{` 对应,标志着整个 `main` 函数的指令序列到此彻底结束。
|
||||
|
||||
---
|
||||
|
||||
以下是这段代码中涉及的英文单词与缩写的中文翻译对照表(理解英语含义后,对于代码的理解也会非常有帮助):
|
||||
|
||||
### 第一个C++程序 基础词汇翻译表(务必记忆!)
|
||||
|
||||
| **代码单词** | **英文全拼** | **中文含义** |
|
||||
| ------------- | ------------------- | -------------------- |
|
||||
| **include** | include | 包含、引入 |
|
||||
| **iostream** | input output stream | 输入输出数据流 |
|
||||
| **using** | using | 使用 |
|
||||
| **namespace** | name space | 命名空间 |
|
||||
| **std** | standard | 标准 |
|
||||
| **int** | integer | 整数 |
|
||||
| **main** | main | 主要的(程序的起点) |
|
||||
| **cout** | console output | 控制台输出 |
|
||||
| **return** | return | 返回 |
|
||||
|
||||
------
|
||||
|
||||
## 第五部分:程序员的注释
|
||||
|
||||
### 一、什么是注释?
|
||||
|
||||
注释是专门写给人看的说明文字,计算机的翻译官(编译器)在将代码翻译成机器语言时,会**完全跳过并忽略**这些内容。
|
||||
|
||||
可以将注释理解为我们在课本空白处书写的学习笔记:老师(代表计算机)在批改作业时不会检查这些笔记,但这些文字能极大地帮助你自己或他人理清程序的逻辑与思路。
|
||||
|
||||
### 二、注释的两种标准写法
|
||||
|
||||
在 C++ 语言中,为了满足不同的说明需求,提供了两种添加注释的语法规范:
|
||||
|
||||
**1. 单行注释 (`//`)**
|
||||
|
||||
- **语法规则**:在代码中使用两个连续的斜杠 `//`。从这两个斜杠开始,直到本行结束的所有文字,都会被编译器自动忽略。通常用于对某单一行的代码进行简短解释。
|
||||
- **代码示例**:
|
||||
|
||||
```cpp
|
||||
cout << "Hello"; // 这是一句单行注释,专门用于解释左侧这行代码的作用
|
||||
```
|
||||
|
||||
**2. 多行注释 (`/* ... */`)**
|
||||
|
||||
- **语法规则**:从 `/*` 符号作为起点开始,直到 `*/` 符号作为终点结束。这两个符号中间包裹的所有文字内容(无论中间跨越了多少行),都会被系统统一认定为注释。此结构非常适合在程序开头书写长篇的整体功能说明。
|
||||
- **代码示例**:
|
||||
|
||||
```C++
|
||||
/* 这是多行注释块
|
||||
此处可以详细书写第一点、第二点...
|
||||
计算机在执行时会完全无视这部分内容
|
||||
*/
|
||||
cout << "World";
|
||||
```
|
||||
|
||||
*(注:在 Dev-C++ 等专业软件中,注释部分通常会被自动标记为绿色或其他浅色,以便与正常执行的代码做出明显的视觉区分。)*
|
||||
|
||||
### 三、为什么在软件开发中要书写注释?
|
||||
|
||||
初学者往往为了节省时间而跳过书写注释的步骤,但书写注释是非常重要的,主要是因为:
|
||||
|
||||
- **防遗忘**:人类的短期记忆是有限的。经过数周或数月后再次阅读自己编写的代码时,如果没有注释辅助回忆,当时设计的复杂计算逻辑往往难以迅速被重新理解。
|
||||
- **团队协作**:在真实的科技企业中,软件开发是一个团队项目,你的代码必定需要交接给其他工程师查阅或修改。清晰、规范的注释是保证团队成员之间能够快速读懂彼此逻辑。
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
### **C++ 初识C++ 课后习题 - 答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 高级,编译
|
||||
2. `F11`
|
||||
3. 控制台
|
||||
4. `main`
|
||||
5. 控制台输出,整数
|
||||
6. 分号 (`;`)
|
||||
7. 单行,多行
|
||||
8. 输入输出流库 (或 标准输入输出功能)
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **B**. 程序是一系列有序的指令。
|
||||
2. **B**. 编译时出现红色错误,意味着编译器(翻译官)读不懂代码,是语法层面的问题。
|
||||
3. **C**. `int main()` 是C++程序的起点和入口。
|
||||
4. **C**. `cout` 用于输出,使用 `<<` 运算符,要输出的文字需用英文双引号包裹。
|
||||
5. **C**. `endl` 是 `end of line` 的缩写,用于换行。
|
||||
6. **B**. 注释是给程序员看的,编译器会忽略。
|
||||
7. **C**. `std` 是 `standard` (标准) 的缩写。
|
||||
8. **A**. `cout` 会紧挨着输出,代码中没有空格也没有 `endl`,所以会连在一起。
|
||||
9. **C**. `return 0;` 代表程序顺利完成任务,正常退出。
|
||||
10. **B**. 使用 `//` 和 `/* */` 注释掉的代码行都不会被编译和执行,所以只有 `Step 2` 会被输出。
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. × (高级语言必须经过编译,翻译成机器语言后才能被计算机执行。)
|
||||
2. √ (C++的语法规定,所有标点必须是英文半角状态。)
|
||||
3. × (所有C++程序都必须有且仅有一个 `main` 函数作为入口。)
|
||||
4. × (`cout` 使用的符号是 `<<`。)
|
||||
5. √ (`#include` 是预处理指令,不是C++语句,所以末尾没有分号。)
|
||||
6. √ (这是单行注释的定义。)
|
||||
7. × (意思是“使用标准命名空间std”。)
|
||||
8. √ (`endl` 会在输出"Hello"后换行,所以"World"会显示在第二行。)
|
||||
9. √ (在文本编辑器中,回车键用于换行。)
|
||||
10. √ (这是C++多行注释的正确语法。)
|
||||
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
### **C++ 初识C++ 课后习题**
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 我们学习的C++属于\_\_\_\_\_\_\_\_\_\_\_\_语言,它需要通过一个叫做“\_\_\_\_\_\_\_\_\_\_\_\_”的过程,翻译成计算机唯一能直接听懂的机器语言。
|
||||
2. 在Dev-C++中,我们可以按键盘上的\_\_\_\_\_\_\_\_\_\_\_\_键来一键“编译并运行”程序。
|
||||
3. 程序编译成功并运行后,会弹出一个黑色的窗口用来显示结果,这个窗口叫做\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
4. 所有C++程序都从\_\_\_\_\_\_\_\_\_\_\_\_开始执行,这是程序的入口。
|
||||
5. `cout` 来自英文 `console output`,是\_\_\_\_\_\_\_\_\_\_\_\_的意思;`int` 来自英文 `integer`,是\_\_\_\_\_\_\_\_\_\_\_\_的意思。
|
||||
6. 在C++代码中,每一条独立的指令语句的末尾都必须使用英文的\_\_\_\_\_\_\_\_\_\_作为结束标记。
|
||||
7. 我们可以在代码中书写两种注释:以 `//` 开始的\_\_\_\_\_\_\_\_\_\_注释,和以 `/*` `*/` 包裹的\_\_\_\_\_\_\_\_\_\_注释。
|
||||
8. `#include <iostream>` 这行代码的作用是引入\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_,这样我们才能使用 `cout` 工具。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 讲义中“把大象塞进冰箱”的例子,是为了说明程序是什么?
|
||||
A. 一种文件格式 B. 一系列需要严格按顺序执行的指令
|
||||
C. 一种计算机硬件 D. 一种只能由 `0` 和 `1` 组成的代码
|
||||
|
||||
( ) 2. 在Dev-C++的编辑区写好C++代码后,如果点击“编译”时,下方出现了红色的错误提示,最可能的原因是?
|
||||
A. 电脑没有连接网络
|
||||
B. 代码存在语法错误,例如拼写错误或使用了中文标点
|
||||
C. 程序运行时间太长
|
||||
D. 程序逻辑太复杂
|
||||
|
||||
( ) 3. 每一个C++程序都必须有且仅有一个的入口是?
|
||||
A. `#include <iostream>` B. `using namespace std;`
|
||||
C. `int main()` D. `return 0;`
|
||||
|
||||
( ) 4. 在C++中,要在屏幕上原样输出一行文字“I love C++”,应该使用下面哪条指令?
|
||||
A. `cout >> "I love C++";` B. `cin << "I love C++";`
|
||||
C. `cout << "I love C++";` D. `main << "I love C++";`
|
||||
|
||||
( ) 5. `endl` 在 `cout` 语句中的主要作用是什么?
|
||||
A. 表示程序结束
|
||||
B. 在输出的末尾添加一个空格
|
||||
C. 输出一个换行符,让后续的输出从下一行开始
|
||||
D. 清除屏幕上所有已有的文字
|
||||
|
||||
( ) 6. 关于代码中的注释,下列说法正确的是?
|
||||
A. 注释是写给计算机执行的指令
|
||||
B. 注释是写给人看的说明文字,计算机会自动忽略它
|
||||
C. 写了注释会让程序运行变慢
|
||||
D. C++只支持 `//` 这一种注释
|
||||
|
||||
( ) 7. 根据讲义中的词汇表,`std` 是哪个单词的缩写?
|
||||
A. student (学生) B. study (学习)
|
||||
C. standard (标准) D. start (开始)
|
||||
|
||||
( ) 8. 阅读以下代码片段,它的最终输出是什么?
|
||||
```cpp
|
||||
cout << "Apple";
|
||||
cout << "Banana";
|
||||
```
|
||||
A. AppleBanana
|
||||
B. Apple Banana
|
||||
C. Apple (然后换行) Banana
|
||||
D. BananaApple
|
||||
|
||||
( ) 9. `return 0;` 这句代码在 `main` 函数中的作用是什么?
|
||||
A. 输出数字0到屏幕上
|
||||
B. 告诉系统程序出错了
|
||||
C. 告诉系统程序正常结束了
|
||||
D. 让程序重新从头执行一次
|
||||
|
||||
( ) 10. 阅读以下代码,控制台最终会显示什么内容?
|
||||
```cpp
|
||||
// cout << "Step 1" << endl;
|
||||
cout << "Step 2" << endl;
|
||||
/*
|
||||
cout << "Step 3" << endl;
|
||||
*/
|
||||
```
|
||||
A. Step 1 B. Step 2
|
||||
C. Step 3 D. Step 1 (然后换行) Step 2 (然后换行) Step 3
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
1. ( ) C++是一门高级语言,计算机可以直接理解并执行C++代码,无需翻译。
|
||||
2. ( ) 在编写C++代码时,输入法必须处于英文半角状态,不能使用中文标点符号。
|
||||
3. ( ) 一个C++程序可以没有 `main` 函数。
|
||||
4. ( ) `cout` 使用的符号是 `>>`,代表数据从变量流向屏幕。
|
||||
5. ( ) `#include <iostream>` 这行代码的末尾不需要加分号 `;`。
|
||||
6. ( ) `//` 符号后面的所有内容,直到这一行的末尾,都会被当作注释处理。
|
||||
7. ( ) `using namespace std;` 的意思是“使用一个名叫std的学生”。
|
||||
8. ( ) 以下代码会在屏幕上分两行输出"Hello"和"World"。
|
||||
```cpp
|
||||
cout << "Hello" << endl;
|
||||
cout << "World";
|
||||
```
|
||||
9. ( ) 计算机键盘上的 `Enter` 键在代码编辑区的主要作用是换行。
|
||||
10. ( ) `/* 我是注释 */` 这种写法是C++中一种正确的注释方式。
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,151 @@
|
||||
# C++ 数学运算与在线评测 讲义
|
||||
|
||||
## 一、 双引号 —— 复读机
|
||||
|
||||
在开始让计算机进行数学运算前,我们必须先记住 `cout` 输出时的规则——**双引号的作用**。
|
||||
|
||||
- **带有双引号 `""`**:计算机将其视为**纯文本**。无论里面写了什么(就算是数学公式),编译器都会像复读机一样原样输出。
|
||||
- **没有双引号**:计算机将其视为**数学公式**。编译器会在后台先计算出精确结果,然后再将结果输出。
|
||||
|
||||
> `cout` 完全可以输出数学运算的结果,前提是**不要**给算式加双引号。
|
||||
|
||||
------
|
||||
|
||||
## 二、 基础运算与编程题目(书本 P4 页 例 1-2)
|
||||
|
||||
**题目回顾(书本 P4 页):** 10 个苹果,小 A 拿走 2 个,Uim 拿走 4 个,八尾勇拿走剩下的。求:①小 A 和 Uim 共拿走多少?②八尾勇拿走多少?(要求:输出两个数字,中间用空格隔开)。
|
||||
|
||||
### 1. 任务拆解与算式转化
|
||||
|
||||
- **第一问**:小 A 和 Uim 一共拿走的数量 $\rightarrow$ 转化为算式:`2 + 4`
|
||||
- **第二问**:八尾勇拿走剩下的数量 $\rightarrow$ 转化为算式:`10 - 2 - 4`
|
||||
|
||||
### 2. 书写代码
|
||||
|
||||
我们的目标是输出,因此必须调用 `cout` 工具。因为要输出两个数字,我们就可以把两个答案拼在一起:
|
||||
|
||||
- **答案一**:`2 + 4`
|
||||
- **分隔符**:`" "`(注意:空格是纯文本,**必须**用双引号包裹,让编译器原样输出)
|
||||
- **答案二**:`10 - 2 - 4`
|
||||
|
||||
**代码语句:**
|
||||
|
||||
```C++
|
||||
cout << 2 + 4 << " " << 10 - 2 - 4;
|
||||
```
|
||||
|
||||
*最后将这行核心的逻辑填入到 `int main() { ... }` 的大括号内部即可完成代码编写。*
|
||||
|
||||
------
|
||||
|
||||
## 三、 实战:将本题代码提交至 OJ 系统 (zmwl.online)
|
||||
|
||||
代码在本地电脑(Dev-C++)运行成功后,我们需要将其提交给**在线评测系统(OJ,考官)进行打分**,在之后的考试或者竞赛中,都是通过将代码提交到在线评测系统中打分的方式来获取成绩。
|
||||
|
||||
### 步骤 1:本地验证
|
||||
|
||||
在正式提交前,先在本地按下 **F11** 观察 Dev-C++ 的控制台。我们通过数学运算能知道最终的答案是 `6` 与 `4`,而题目要求的格式是输出两个数字,中间用空格隔,所以最终显示的数字必须是 `6 4`,不能有多余的数据或标点。
|
||||
|
||||
### 步骤 2:登录
|
||||
|
||||
1. **打开网站**:浏览器地址栏输入 `zmwl.online` 并回车。
|
||||
2. **账号登录**:输入用户名,初始密码统一为 `zmwl0000`。
|
||||
3. **寻找考题**:点击上方“题库”,在列表中点击编号为 **B0001** 的题目进入详情页。
|
||||
|
||||
### 步骤 3:代码复制搬运 (快捷键操作)
|
||||
|
||||
切换回 Dev-C++ 软件窗口,执行以下键盘指令:
|
||||
|
||||
- **全选**:按住 **Ctrl** 键不放,按 **A** 键。(代码区背景变蓝,全部圈中)
|
||||
- **复制**:按住 **Ctrl** 键不放,按 **C** 键。(代码存入电脑的剪贴板中)
|
||||
|
||||
### 步骤 4:递交与查收结果
|
||||
|
||||
1. **准备粘贴**:回到浏览器 B0001 题目页,点击“**递交**”按钮,进入一个大空白输入框。
|
||||
2. **执行粘贴**:鼠标左键点击空白框确保光标闪烁,按住 **Ctrl** 键不放,按 **V** 键。
|
||||
3. **提交检验**:确认代码无误后,点击系统底部的递交按钮,等待系统判定正误。
|
||||
|
||||
------
|
||||
|
||||
## 四、 C++ 的特殊数学法则:除法与取余
|
||||
|
||||
C++ 中的加、减、乘以及运算优先级与小学数学一致,但**除法 (`/`)** 存在差异。
|
||||
|
||||
### 1. 除法 (`/`) 的两种形态
|
||||
|
||||
| **形态** | **触发条件** | **运算规则** | **代码示例** | **输出结果** |
|
||||
| -------------- | ------------------------ | ------------------------------------ | ------------------ | ------------ |
|
||||
| **整数相除** | 除数和被除数**都是整数** | 小数部分被**直接截断**(不四舍五入) | `cout << 7 / 2;` | **3** |
|
||||
| **浮点数相除** | 至少有一个数是**小数** | 自动开启浮点除法,保留小数部分 | `cout << 7.0 / 2;` | **3.5** |
|
||||
|
||||
> **总结:**
|
||||
>
|
||||
> 1. 整数乘/除一个浮点数,结果是浮点数。
|
||||
>
|
||||
> 2. 整数加上一个浮点数,结果也是浮点数。
|
||||
>
|
||||
> *(例:6 元和 5 元平分,算式应写为 `(6 + 5) / 2.0` 以获取精确的小数结果)*
|
||||
|
||||
### 2. 取余运算 (`%`)
|
||||
|
||||
百分号 `%` 在 C++ 中是**取模运算(求余数)**。
|
||||
|
||||
- **`/` 关心商**:每个人平均分到几个?
|
||||
- **`%` 关心余数**:大家都分完一样多后,还剩下几个?
|
||||
|
||||
**例 1-3 分苹果(题目编号 B0002,书本 P6 页):**
|
||||
|
||||
14 个苹果均分给 4 名同学。
|
||||
|
||||
```C++
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main(){
|
||||
cout << 14 / 4 << endl; // 每人分得几个? (输出 3)
|
||||
cout << (14 / 4) * 4 << endl; // 一共分出去多少?(输出 12)
|
||||
cout << 14 % 4 << endl; // 放回冰箱几个(即求余数)?(输出 2)
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
## 五、 科学表示法与数学工具调用
|
||||
|
||||
### 1. 科学计数法(例 1-5)
|
||||
|
||||
在 C++ 中处理极大或极小的数字时,经常遇到包含字母 `e` 的表示法:
|
||||
|
||||
- `5e6` 代表 $5 \times 10^6$(即 5000000)。
|
||||
- `5e-6` 代表 $5 \times 10^{-6}$(即 0.000005)。
|
||||
|
||||
### 2. 物理与几何题(例 1-6 & 例 1-7)
|
||||
|
||||
- **火车相遇问题(例 1-6)**:纯基础运算。相对速度与相对距离公式 $\rightarrow$ `cout << (260 + 220) / (12 + 20);`
|
||||
- **对角线问题(例 1-7)**:长宽为 6 和 9 的长方形,根据勾股定理求对角线 $\sqrt{6^2+9^2}$。
|
||||
|
||||
### 3. 引入高级数学工具:`<cmath>`
|
||||
|
||||
C++ 内部预制了大量可以直接使用的数学工具(函数)。要使用它们,**必须在基础代码顶部加上 `#include <cmath>`**。
|
||||
|
||||
- **开平方工具:`sqrt()`**
|
||||
- **用法**:把需要开根号的数字丢进括号里。
|
||||
- **示例**:`cout << sqrt(9);` (输出 3)
|
||||
- **求次方工具:`pow(x, y)`**
|
||||
- **用法**:计算 $x$ 的 $y$ 次方,数字之间用逗号隔开。
|
||||
- **示例**:`cout << pow(2, 3);` (计算 $2^3$,输出 8)
|
||||
|
||||
**例1-7 对角线问题代码:**
|
||||
|
||||
```C++
|
||||
#include <iostream>
|
||||
#include <cmath> // 必须引入数学的工具箱
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
// 计算过程:先算出 6 的 2 次方加上 9 的 2 次方,再对总和进行开根号
|
||||
cout << sqrt(pow(6, 2) + pow(9, 2)) << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
### 参考答案
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `5 + 3`
|
||||
2. `8`
|
||||
3. `4`
|
||||
4. `1`
|
||||
5. `4.5`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **(B)** (带双引号,原样输出)
|
||||
2. **(A)** (没有双引号,计算结果)
|
||||
3. **(C)** (整数除法,`13 / 5` 商2余3,结果为2)
|
||||
4. **(C)**
|
||||
5. **(C)** (至少有一个数是小数,才能触发浮点数除法)
|
||||
6. **(B)** (先计算 `2+4` 得 `6`,然后输出空格,再计算 `10-2-4` 得 `4`)
|
||||
7. **(B)**
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. **(×)** (带双引号会原样输出 "3 * 4")
|
||||
2. **(√)** (讲义中明确指出是“直接截断”,不四舍五入)
|
||||
3. **(√)** (这是触发浮点数除法的条件)
|
||||
4. **(×)** (讲义中强调,提交前最好先在本地验证)
|
||||
5. **(√)** (这是 `%` 运算符的定义)
|
||||
6. **(×)** (这是求余数,`5` 除以 `2` 商 `2` 余 `1`,结果是 `1`)
|
||||
7. **(√)** (空格是文本,需要用双引号包围)
|
||||
@@ -0,0 +1,89 @@
|
||||
### C++ 数学运算与评测 课后习题
|
||||
|
||||
姓名: _________________________________________________________
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 代码 `cout << "5 + 3";` 的输出结果是:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
2. 代码 `cout << 5 + 3;` 的输出结果是:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
3. 在 C++ 中,两个整数相除得到的结果会\_\_\_\_\_\_\_\_\_\_\_(填写 舍弃/保留)小数。
|
||||
4. `%` 符号在 C++ 中的意义是:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
5. `cout << 9 / 2;` 的输出结果是:\_\_\_\_\_\_\_\_\_\_。
|
||||
6. `cout << 15 / 2.0;` 的输出结果是:\_\_\_\_\_\_\_\_\_\_。
|
||||
7. `cout << 9 % 2;` 的输出结果是:\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 执行 `cout << "10 / 2";` 后,屏幕上会显示什么?
|
||||
A. `5` B. `10 / 2` C. `10/2` D. `2`
|
||||
|
||||
( ) 2. 执行 `cout << 10 / 2;` 后,屏幕上会显示什么?
|
||||
A. `5` B. `10 / 2` C. `10/2` D. `2`
|
||||
|
||||
( ) 3. 执行 `cout << 13 / 5;` 后,屏幕上会显示什么?
|
||||
A. `3` B. `2.6` C. `2` D. `1`
|
||||
|
||||
( ) 4. 在 C++ 中,`%` 运算符代表什么?
|
||||
A. 百分比 B. 除法 C. 取余数 D. 乘法
|
||||
|
||||
( ) 5. 如何计算 `10` 除以 `4` 才能得到带有小数的结果 `2.5`?
|
||||
A. `cout << 10 / 4;`
|
||||
B. `cout << 10 % 4;`
|
||||
C. `cout << 10.0 / 4;`
|
||||
D. `cout << "10 / 4";`
|
||||
|
||||
( ) 6. 对于代码代码是 `cout << 2 + 4 << " " << "10 - 2 - 4";`,它的最终输出结果是?
|
||||
A. `6 10-2-4` B. `6 4` C. `64` D. `6, 4`
|
||||
|
||||
( ) 7. 在线评测系统 (OJ) 的主要作用是什么?
|
||||
A. 帮助我们写代码的软件
|
||||
B. 用来运行和评判我们代码对错的“考官”
|
||||
C. 一个只能存储代码的网站
|
||||
D. C++ 的一个内置功能
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
( ) 1. `cout << "3 * 4";` 这行代码会输出 12。
|
||||
( ) 2. 整数除法 `7 / 3` 的结果是 `2`,因为小数部分被直接舍弃,而不是四舍五入。
|
||||
( ) 3. 在 C++ 中,只要除法算式中有一个数字是小数(如 `5.0 / 2`),计算结果就会保留小数。
|
||||
( ) 4. 把代码提交到在线评测系统(OJ)之前,不需要在自己的电脑上运行测试。
|
||||
( ) 5. `%` 运算符可以用来计算一个数除以另一个数的余数。
|
||||
( ) 6. `cout << 5 % 2;` 的结果是 2.5。
|
||||
( ) 7. 在 `cout` 语句中,如果想输出一个空格,必须写成 `cout << " ";`。
|
||||
|
||||
#### **四、 默写题**
|
||||
|
||||
请在下方的空白处,默写出基本程序的框架代码,并简要说明每一句代码的意义。
|
||||
|
||||
```cpp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,203 @@
|
||||
# C++ 变量与常量 讲义
|
||||
|
||||
## 一、 为什么我们需要变量?
|
||||
|
||||
**例 1-8:存钱问题(参考书本 P9 1.3 节)**
|
||||
Uim 的银行账户里原有 100 元。经过了以下操作:
|
||||
|
||||
1. 往里面存了 10 元;
|
||||
2. 购物花掉了 20 元;
|
||||
3. 把里面的钱全部取出。
|
||||
*需求:在每次操作后输出账户余额。*
|
||||
|
||||
**分析:** 这个问题无法用一个简单的算式一次性解决。我们需要在每一步操作后,把算出来的**中间结果**保存下来,留给下一步继续计算。在编程中,用来**存储计算中间结果**的工具,就叫做**变量 **。
|
||||
|
||||
---
|
||||
|
||||
## 二、 计算机里的容器
|
||||
|
||||
在生活中,我们用**容器**(如碗、盘子)来存放物品。在计算机中,我们用**变量**来存放数据。
|
||||
|
||||
**做菜的比喻(参考书本 P15 第一自然段):**
|
||||
|
||||
* **原材料** = 我们要处理的数据(数字、字符等)。
|
||||
* **容器** = 变量(用来装数据)。
|
||||
* **操作台** = 计算机的内存。
|
||||
|
||||
**内存的物理形态:**
|
||||
内存就像一排排的小抽屉,一个抽屉就是一个**字节 (Byte)**。常用 1 字节 = 8 位(bit),每一位只能存 0 或 1。位是最小的数据单位。不同的数据类型,占用的字节数可能不同。
|
||||
|
||||
---
|
||||
|
||||
## 三、 声明变量:挑个柜子写上自己的名字
|
||||
|
||||
如果你想占用内存里的“抽屉”,必须先向计算机**声明**,否则别人(其他程序)可能也会去用这个抽屉,导致数据大乱斗。
|
||||
|
||||
**声明变量的格式:** `数据类型 + 变量名;`
|
||||
|
||||
### 1. 数据类型(选多大的柜子)
|
||||
|
||||
*参考书本 P16 表 2-1*
|
||||
做菜时,装高汤不能用菜篓子。编程时,不同的数据也要选不同类型的柜子:
|
||||
|
||||
| 分类 | 类型名称 | 关键字 | 说明 / 存储范围 |
|
||||
| ----------------- | ------------ | ----------- | ----------------------------------------------------- |
|
||||
| **整型 (整数)** | 短整型 | `short` | -32768 ~ 32767 |
|
||||
| | **基本整型** | `int` | **-2147483648 ~ 2147483647 (最常用)** |
|
||||
| | 长整型 | `long long` | 存非常大的整数 |
|
||||
| **浮点型 (小数)** | 单精度型 | `float` | 通常约有 6~7 位十进制有效数字 |
|
||||
| | **双精度型** | `double` | **通常约有 15~16 位十进制有效数字 (最常用)** |
|
||||
| **字符型** | 字符型 | `char` | 单个字符,例如 `A`, `!`, `?`, `b` 等 |
|
||||
| **布尔型** | 布尔型 | `bool` | 只有真 (`true` 正确的) 和假 (`false` 错误的) 两种状态 |
|
||||
|
||||
### 2. 变量名命名规则(贴什么名字)
|
||||
|
||||
*参考书本 P11 第三自然段*
|
||||
变量名必须做到**见名知意**(具有自解释性,比如用 `balance` 表示余额,用 `age` 表示年龄)。
|
||||
|
||||
* **强制法则:** 只能由字母、数字和下划线(`_`)组成。
|
||||
* **数字禁忌:** 数字**绝对不能**出现在第一个位置上!(`num1` 正确,`1num` 错误)。
|
||||
* **避开关键字:** 不能使用 C++ 自带的指令词(如 `const`, `return`, `int`)。
|
||||
* **不可重复:** 同一作用域(范围)内,名字不能重复,你不能命名两个柜子都叫做`pingguo`。
|
||||
* **语言限制:** 英文不好可以用拼音(如 `pingguo`),但**严禁使用中文**!
|
||||
|
||||
---
|
||||
|
||||
## 四、 赋值与初始化:往柜子里装东西
|
||||
|
||||
声明了柜子后,我们如何把数据放进去呢?这就需要用到**赋值符 (`=`)**。
|
||||
**注意:** 在 C++ 中,`=` 不叫“等于”,它叫“赋值”。它的动作是:**将等号右边的数值,粘贴(覆盖)给左边的变量。**
|
||||
|
||||
### 1. 变量的初始化
|
||||
|
||||
初始化指的是**在定义变量的同时就给它赋值**,避免柜子里残留以前的垃圾数据。比方说之前有人往这个柜子里放了化学试剂,如果你直接往里放食材的话,肯定就会有危险!
|
||||
|
||||
```cpp
|
||||
int num; // 未初始化,如果直接去读取里面的数据,会读取到随机的垃圾数字
|
||||
int a = 10; // 安全:定义整数 a,并初始化为 10
|
||||
double b = 3.123; // 安全:定义小数 b,并初始化为 3.123
|
||||
```
|
||||
|
||||
### 2. 连续定义与赋值(补充知识,请记在书本 P15 页)
|
||||
|
||||
如果我们需要同时申请多个同类型的变量,可以用逗号 `,` 连写:
|
||||
|
||||
```cpp
|
||||
int a, b; // 同时申请两个空柜子 a 和 b
|
||||
int x = 10, y = 20; // 同时申请两个柜子 x 和 y 并装入初始值
|
||||
```
|
||||
|
||||
### 3. 赋值的覆盖特性与累加
|
||||
|
||||
对变量的赋值是一个**覆盖**过程。新数据装进去,旧数据就彻底消失了。
|
||||
|
||||
**变量的自我更新:**
|
||||
|
||||
```cpp
|
||||
int num1 = 1;
|
||||
num1 = num1 + 7; // 此时 num1 变成了 8
|
||||
```
|
||||
|
||||
**简单写法(书本 P10 第六自然段):**
|
||||
为了让代码更简洁,程序员发明了简写形式:
|
||||
|
||||
* `num1 += 7;` 完全等同于 `num1 = num1 + 7;`
|
||||
* `a += b;` 完全等同于 `a = a + b;`
|
||||
|
||||
---
|
||||
|
||||
## 五、 常量
|
||||
|
||||
*例 1-9(P10 页):求圆的周长面积和体积*
|
||||
|
||||
在计算圆周率 $\pi$ 时,我们需要一个容器来装 `3.14159`。但是,圆周率是一个自然界的真理,在程序运行期间我们**不允许它被意外修改**。
|
||||
|
||||
这时,我们需要使用关键字 **`const`** 来声明一个**常量**。因为在实际的工程中,一个软件是由很多程序员开发的,定义常量就能让别的程序员知道我定义的这个变量不能修改,改了会出问题。
|
||||
|
||||
**常量的规则:**
|
||||
|
||||
1. **必须在声明时就给它初始化**,否则编译直接报错。
|
||||
2. **终生不可更改**,不能再通过赋值符 `=` 修改它。
|
||||
|
||||
```cpp
|
||||
// 声明一个双精度浮点数常量 PI
|
||||
const double PI = 3.14159;
|
||||
// PI = 3.0; // 如果写这行代码,计算机会报错!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、 变量与字符串的区别
|
||||
|
||||
在结合 `cin` 和 `cout` 使用时,初学者最容易在输出格式上栽跟头。请大家仔细观察以下四种写法的输出区别(假设前面已经运行了 `int x = 5, y = 6;`):
|
||||
|
||||
| 代码写法 | 控制台实际输出 | 解析 |
|
||||
| -------------------------- | -------------- | ----------------------------------------- |
|
||||
| `cout << x + y;` | **11** | 没有双引号,执行后台数学计算。 |
|
||||
| `cout << "x+y";` | **x+y** | 有双引号,纯文本复读机,原样输出。 |
|
||||
| `cout << x << "+" << y;` | **5+6** | 变量(抽出数字)与纯文本(加号)的拼接。 |
|
||||
| `cout << "x+y=" << x + y;` | **x+y=11** | 前面输出纯文本提示音 + 后面输出计算结果! |
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## 六、 综合实战演练
|
||||
|
||||
**练习:理解并练习书本例 1-10(P11 页),猴子吃桃问题**
|
||||
|
||||
**题目描述:** 猴子第一天吃了所有桃子的一半又多吃了一个;第二天又吃了剩下的一半多一个;第三天同理。第四天发现只剩下一个了。问原来有几个?
|
||||
|
||||
**解题思维(逆向):**
|
||||
正向推导较为复杂,但如果运用倒推法,问题就能较为简单的解决。
|
||||
|
||||
* 第四天:剩下 1 个。
|
||||
* 第三天:把第四天的数量加上它贪嘴多吃的那 1 个(吐出来),然后再翻倍。
|
||||
* 第二天、第一天:重复同样的动作。
|
||||
*我们可以利用变量来持续覆盖、更新当前的桃子数。*
|
||||
|
||||
**代码思路:**
|
||||
|
||||
- **第一步:`int peach = 1;`**
|
||||
- 计算机在内存里找了一个整数大小的空抽屉,在抽屉外面贴上了一个标签,名字叫 `peach`(桃子)。然后,把第四天最后剩下的数字 **1**,放进了抽屉里。 *【此时 peach =1】*
|
||||
|
||||
- **第二步:`peach = (peach + 1) * 2;`**
|
||||
- 这行代码在数学上是不成立的,但在编程里,我们要**先看等号右边,再看等号左边**。 计算机先执行右边的计算:它拉开名为 `peach` 的抽屉,发现里面是 1。于是它在后台的大脑里计算 `(1 + 1) * 2`,算出来的结果是 4。 接着,执行等号(赋值)的动作:计算机地把抽屉里原来的 1 扔掉,把刚刚算出来的 **4** 装了进去!这代表第三天开始时有 4 个桃子。 *【此时 peach = 4】*
|
||||
|
||||
- **第三步:`peach = (peach + 1) * 2;`**
|
||||
- 代码跟第二步长得一模一样,但结果完全不同! 计算机再次拉开 `peach` 抽屉,此时里面装的已经是 4 了。计算机在大脑里计算 `(4 + 1) * 2`,得到 10。 然后再次执行覆盖:把 4 扔掉,把 **10** 装进抽屉。这代表第二天开始时有 10 个桃子。 *【此时 peach = 10】*
|
||||
|
||||
- **第四步:`peach = (peach + 1) * 2;`**
|
||||
- 最后一次倒推。拉开抽屉拿出 10,计算 `(10 + 1) * 2`,得到 22。 扔掉 10,把 **22** 放进抽屉里。这代表第一天小猴子刚买回来的桃子总数。 *【此时 peach = 22】*
|
||||
|
||||
- **第五步:`cout << peach;`**
|
||||
- 任务完成!我们 `cout` 输出 `peach` 抽屉,把它现在装的最终数字展示在屏幕上。屏幕上将打印出:**22**。
|
||||
|
||||
**我们全程只用了一个名叫 `peach` 的抽屉,但通过反复使用 `=`(赋值符),我们让抽屉里的数据根据题意进行了变化和覆盖。**
|
||||
|
||||
**程序代码:**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
// 1. 申请抽屉并放入第四天的数量
|
||||
int peach = 1;
|
||||
|
||||
// 2. 倒推第三天的数量
|
||||
peach = (peach + 1) * 2;
|
||||
|
||||
// 3. 倒推第二天的数量
|
||||
peach = (peach + 1) * 2;
|
||||
|
||||
// 4. 倒推第一天(刚买回来时)的数量
|
||||
peach = (peach + 1) * 2;
|
||||
|
||||
// 5. 展示抽屉里最终的结果
|
||||
cout << peach << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
### 参考答案
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 变量
|
||||
2. `int`
|
||||
3. `double`
|
||||
4. 赋值
|
||||
5. `100`
|
||||
6. `+=`
|
||||
7. `const`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. C (变量名不能以数字开头)
|
||||
2. C
|
||||
3. B
|
||||
4. B
|
||||
5. C
|
||||
6. D (`count = 1;` 是直接赋值,不是在原有基础上加1)
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √
|
||||
2. × (在C++中 `=` 是赋值,`==` 才是判断相等)
|
||||
3. × (常量必须在定义时就初始化)
|
||||
4. × (未初始化的变量里存放的是不确定的“垃圾值”)
|
||||
5. √
|
||||
6. √
|
||||
@@ -0,0 +1,73 @@
|
||||
### C++ 变量与常量 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 在编程中,我们用来存放数据的“容器”,叫做 \_\_\_\_\_\_\_\_。
|
||||
|
||||
2. 如果想定义一个可以存放整数的变量 `age`,代码应该写成:\_\_\_\_\_\_\_\_ `age;`
|
||||
|
||||
3. 如果想定义一个可以存放小数(例如 `1.75`)的变量 `height`,最常用的数据类型关键字是 \_\_\_\_\_\_\_\_。
|
||||
|
||||
4. 在 C++ 中,符号 `=` 不叫“等于”,而叫做 \_\_\_\_\_\_\_\_符。
|
||||
|
||||
5. 阅读代码 `int score = 90; score = 100;`,执行后 `score` 变量中最终存放的值是 \_\_\_\_\_\_\_\_。
|
||||
|
||||
6. 为了让代码 `num = num + 5;` 更简洁,我们可以使用简写形式:`num` \_\_\_\_\_\_\_\_ `5;`
|
||||
|
||||
7. 如果想定义一个值固定为 `3.14` 且不允许被修改的常量 `PI`,需要在定义的最前面加上关键字 \_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 下列哪个是**不合法**的变量名?
|
||||
A. `my_score`
|
||||
B. `num1`
|
||||
C. `1st_place`
|
||||
D. `age`
|
||||
|
||||
( ) 2. 我们用什么数据类型来存放单个字符,比如 `'A'`?
|
||||
A. `int`
|
||||
B. `double`
|
||||
C. `char`
|
||||
D. `bool`
|
||||
|
||||
( ) 3. `int num = 10;` 这行代码中的 `=` 是什么意思?
|
||||
A. 判断 `num` 是否等于 `10`
|
||||
B. 将 `10` 这个数值放进 `num` 变量里
|
||||
C. 声明 `num` 是一个常量
|
||||
D. 将 `num` 的值加上 `10`
|
||||
|
||||
( ) 4. `const` 关键字定义出来的常量,有什么特点?
|
||||
A. 它的值在程序运行中可以被多次修改
|
||||
B. 它必须在定义的时候就给定一个初始值,并且之后不能再修改
|
||||
C. 它只能用来存放整数
|
||||
D. 它不需要指定数据类型
|
||||
|
||||
( ) 5. 阅读以下代码:
|
||||
```cpp
|
||||
int apples = 10;
|
||||
apples = apples - 3;
|
||||
cout << apples;
|
||||
```
|
||||
程序的输出结果是?
|
||||
A. `10`
|
||||
B. `3`
|
||||
C. `7`
|
||||
D. `13`
|
||||
|
||||
( ) 6. 哪条语句和 `count = count + 1;` 是**不等价**的?
|
||||
A. `count += 1;`
|
||||
B. `count++;`
|
||||
C. `++count;`
|
||||
D. `count = 1;`
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. C++ 的变量名可以由字母、数字、下划线组成,但不能以数字开头。
|
||||
( ) 2. 在数学中 `=` 表示等于,在 C++ 中也完全一样,表示判断两边是否相等。
|
||||
( ) 3. 定义一个常量时可以不给它初始值,等需要的时候再赋值。
|
||||
( ) 4. `int num;` 这样定义出来的变量,里面存放的数值一定是 `0`。
|
||||
( ) 5. 当我们写 `score = 95;` 时,如果 `score` 变量里原来存了 `80`,那么 `80` 会被 `95` 覆盖掉。
|
||||
( ) 6. 猴子吃桃问题中,`peach = (peach + 1) * 2;` 这行代码利用了变量值可以被反复更新覆盖的特性。
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,82 @@
|
||||
# C++ 输入 (`cin`) 讲义
|
||||
|
||||
## 一、 程序只能算固定数据吗?
|
||||
|
||||
我们之前写的代码,所有的数字都是直接写在程序里的,比如 `int a = 5; int b = 3;`。这种写法把**数据写死**了。
|
||||
大家思考一下,如果用户明天想算 `100 + 200` 怎么办?难道每次都要让程序员打开代码,改完数字再重新算一次吗?这显然是不现实的!
|
||||
一个真正有价值的程序,应该是**智能的**——它能够随时接收用户提供的新数据,并自动计算出结果。今天,我们就要学习如何让程序接收用户提供的数据。
|
||||
|
||||
## 二、 认识 `cin`:控制台的数据接收员
|
||||
|
||||
为了让程序接收用户的键盘输入,C++ 提供了一个强大的工具:**`cin`**。
|
||||
|
||||
* **含义**:**`cin`** 是 Console Input(控制台输入)的缩写, c 对应着 Console, in 对应着 input。
|
||||
* **作用**:**让用户在黑框框里==用键盘==输入数据**,然后程序会自动把这个数据==存入==我们提前准备好的==变量==中。
|
||||
* **`cin` 使用 >> 运算符跟上准备好的变量来接收用户输入**。
|
||||
|
||||
### 1. `cin` 的运作过程
|
||||
|
||||
我们来看看 `cin` 是如何与我们之前学习的变量配合的:
|
||||
|
||||
```cpp
|
||||
int num;
|
||||
cin >> num;
|
||||
cout << num;
|
||||
```
|
||||
|
||||
1. **`int num;`** $\rightarrow$ 程序向内存申请了一个整数类型的空柜子,并在外面贴上名字标签 `num`。
|
||||
2. **`cin >> num;`** $\rightarrow$ 程序==暂停运行==,等待用户操作。用户在键盘上敲下数字 `7` 并按下回车。**`>>`(称为提取符)**就像传送带一样,把键盘上的 `7` 抓过来,放进了名为 `num` 的抽屉里。
|
||||
3. **`cout << num;`** $\rightarrow$ 获取名为 `num` 抽屉里的数据,并将其展示在屏幕上(输出 7)。
|
||||
|
||||
### 2. 语法与规则
|
||||
|
||||
输入单个数据:
|
||||
|
||||
**==语法格式==:** `cin >> 变量名;`
|
||||
|
||||
如果你想一次性让用户输入多个数据,那就需要准备多个变量,然后把传送带连起来用:
|
||||
|
||||
**==语法格式==:** `cin >> 变量名 >> 变量名 >> 变量名;` (可以通过 `>> 变量名` 的格式继续扩展)
|
||||
|
||||
```cpp
|
||||
int a, b, c;
|
||||
cin >> a; // 接收用户输入的一个整数到变量 a 中
|
||||
cin >> b >> c; // 依次接收用户输入的两个整数到变量 b, c 中
|
||||
```
|
||||
|
||||
> **输入规则:**
|
||||
> 当使用 `cin >> a >> b;` 时,用户在黑框框里输入数据,**必须使用“空格”或者“回车”来隔开两个数字**(比如输入 `5 10`)。`cin` 它只要一遇到空格或回车,就知道第一个数据输入结束了,准备把下一个数据放进第二个抽屉里。
|
||||
|
||||
---
|
||||
|
||||
## 三、 解决题目中要求有输入的题目
|
||||
|
||||
现在我们拥有了所有的基础工具(变量、加减乘除、输入、输出)。接下来,我们要做一道完整的带有输入程序题。务必要记住:
|
||||
|
||||
==**"输入 -> 处理 -> 输出" 是完成程序题目的三个基本步骤。**==
|
||||
|
||||
**题目描述:请你实现输入两个整数,输出这两个整数的差。**
|
||||
*(样例输入:2 3 $\rightarrow$ 样例输出:-1;样例输入:10 2 $\rightarrow$ 样例输出:8)*
|
||||
|
||||
**分析思路**:
|
||||
|
||||
1. **提取有效信息**:题目需要什么?(**==输入两个数==** $\rightarrow$ 相减 $\rightarrow$ 输出结果)。
|
||||
2. **整理思路**:
|
||||
* 准备两个变量(空抽屉)装输入的数。
|
||||
* 用 `cin` 把用户敲的字放进抽屉。
|
||||
* 处理数据:拿出来相减,结果放进第三个抽屉。
|
||||
* 用 `cout` 展示第三个抽屉。
|
||||
|
||||
|
||||
3. **将思路一步步翻译为C++ 代码**:
|
||||
```cpp
|
||||
int num1, num2; // 准备抽屉
|
||||
cin >> num1 >> num2; // 接收输入
|
||||
int diff = num1 - num2; // 计算并存入新抽屉
|
||||
cout << diff; // 输出结果
|
||||
```
|
||||
|
||||
|
||||
4. **编译运行**:按下 F11。如果有报错,不要慌,检查是不是漏了分号,或者 `>>` 和 `<<` 的方向写反了。
|
||||
5. **输入测试数据,验证结果**:在弹出的黑框里输入测试用例 `2 3`,看看结果是不是 `-1`。
|
||||
6. **修正错误**:如果输出不对(比如输出了 5),说明语法没问题,但是**逻辑错了**。回去检查代码,是不是把减号写成加号了?修改后重新测试,直到完全正确为止。
|
||||
Binary file not shown.
@@ -0,0 +1,37 @@
|
||||
### **C++ `cin` 输入 课后习题 - 答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. Console Input (或 控制台输入)
|
||||
2. `>>` , 提取运算符
|
||||
3. 输入 , 处理
|
||||
4. 暂停 (或 阻塞)
|
||||
5. 空格 , 回车
|
||||
6. 定义
|
||||
7. 放进
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **D**. `cin` 的核心就是获取键盘输入。
|
||||
2. **C**. `cin` 使用提取运算符 `>>`,方向是从 `cin` 流向变量。
|
||||
3. **C**. 链式输入使用 `>>` 连接多个变量。
|
||||
4. **C**. `cin` 默认使用空白字符(空格、回车等)作为分隔符,逗号不是空白字符,无法正确分割。
|
||||
5. **B**. `cin` 使得程序可以处理运行时才给定的数据,变得通用和灵活。
|
||||
6. **B**. 程序先定义变量,然后通过 `cin` 获取值,再进行计算和输出,是完整的“输入-处理-输出”流程。
|
||||
7. **C**. 两种写法在功能上完全相同,都能读取两个变量,但链式写法更为常用和简洁。
|
||||
8. **B**. 程序能运行但结果不对,说明语法正确(不是CE),但计算或处理的思路(逻辑)错了。
|
||||
9. **B**. `cin >> a;` 只会读取一个整数。它读到 `5`,遇到空格,就认为第一个数的输入结束了,所以 `a` 的值是 `5`。`6` 会留在输入缓冲区中等待下一次 `cin` 读取。
|
||||
10. **C**. `int a, b;` 定义变量,`cin >> a >> b;` 使程序暂停,等待输入。
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. × ( `c` 代表 "Console" (控制台)。)
|
||||
2. √ (必须先准备好“抽屉”,才能往里面放东西。)
|
||||
3. √ (`cin` 是输入,`cout` 是输出,方向和作用都相反。)
|
||||
4. √ (`cin` 在读取数据前会跳过所有空白字符。)
|
||||
5. × (回车也是一种空白分隔符,所以可以一个数字一行,分两行输入。)
|
||||
6. √ (这是讲义中强调的程序设计基本结构。)
|
||||
7. √ (这正是引入 `cin` 的核心价值。)
|
||||
8. × (讲义中的6步法强调,应该先整理思路,再翻译成代码。)
|
||||
9. √ (提取运算符 `>>` 的作用就是将读取到的值赋给变量。)
|
||||
10. × ( `cout` 应该使用插入运算符 `<<`,正确的写法是 `cout << "请输入一个数字";`。)
|
||||
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
### **C++ `cin` 输入 课后习题**
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 在C++中,`cin` 是 \_\_\_\_\_\_\_\_\_\_\_\_\_\_ 的英文缩写,它的主要作用是接收用户的键盘输入。
|
||||
2. `cin` 使用的运算符是 \_\_\_\_\_\_\_\_\_\_,这个运算符被称为 \_\_\_\_\_\_\_\_\_\_,它的箭头方向形象地表示数据从键盘流向变量。
|
||||
3. 一个有输入功能的程序,其基本流程可以分为三个步骤:\_\_\_\_\_\_\_\_\_\_、处理和输出。
|
||||
4. 当程序执行到 `cin >> a;` 语句时,会\_\_\_\_\_\_\_\_\_\_运行,并等待用户输入数据。
|
||||
5. `cin` 通过空白字符来区分多个输入数据,最常见的两种空白字符是\_\_\_\_\_\_\_\_\_\_和\_\_\_\_\_\_\_\_\_\_。
|
||||
6. 在使用 `cin >> num;` 之前,必须先\_\_\_\_\_\_\_\_\_\_变量 `num`,为输入的数据准备好存放空间。
|
||||
7. 讲义中用生活中的例子做比喻,把变量比作“抽屉”,那么 `cin` 的作用就是把外面的数据\_\_\_\_\_\_\_\_\_\_“抽屉”里。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 在C++中,`cin` 的核心功能是什么?
|
||||
A. 在屏幕上打印文字和符号
|
||||
B. 让程序暂停指定的时间
|
||||
C. 定义新的变量类型
|
||||
D. 从键盘读取数据并存入变量
|
||||
|
||||
( ) 2. 下面哪条语句可以正确地从键盘读取一个整数并存放到变量 `score` 中?
|
||||
A. `cin << score;`
|
||||
B. `cout >> score;`
|
||||
C. `cin >> score;`
|
||||
D. `cout << score;`
|
||||
|
||||
( ) 3. 如果要用一条语句连续读取用户的两个整数,分别存入变量 `width` 和 `height`,应该怎么写?
|
||||
A. `cin >> width, height;`
|
||||
B. `cin >> width; height;`
|
||||
C. `cin >> width >> height;`
|
||||
D. `cin << width << height;`
|
||||
|
||||
( ) 4. 对于语句 `cin >> x >> y;`,用户在键盘上**不正确**的输入方式是?
|
||||
A. 输入 `10`,按空格键,再输入 `20`,按回车键
|
||||
B. 输入 `10`,按回车键,再输入 `20`,按回车键
|
||||
C. 输入 `10,20`,按回车键
|
||||
D. 输入 `10`,按多个空格键,再输入 `20`,按回车键
|
||||
|
||||
( ) 5. `cin` 这个工具主要解决了程序中的什么根本性问题?
|
||||
A. 计算速度太慢的问题
|
||||
B. 只能计算和处理“写死”在代码里的固定数据的问题
|
||||
C. 无法输出中文的问题
|
||||
D. 代码必须从 `main` 函数开始的问题
|
||||
|
||||
( ) 6. 阅读以下代码,它的功能是什么?
|
||||
```cpp
|
||||
int base, height;
|
||||
cin >> base >> height;
|
||||
int area = base * height / 2;
|
||||
cout << area;
|
||||
```
|
||||
A. 计算一个固定三角形的面积
|
||||
B. 输入两个整数作为底和高,然后计算并输出三角形的面积
|
||||
C. 只输入两个整数,不进行任何计算
|
||||
D. 这段代码有语法错误,无法运行
|
||||
|
||||
( ) 7. `cin >> a; cin >> b;` 和 `cin >> a >> b;` 这两种写法是什么关系?
|
||||
A. 前者正确,后者错误
|
||||
B. 两者功能完全不同
|
||||
C. 两者功能等价,但后者更简洁
|
||||
D. 后者正确,前者错误
|
||||
|
||||
( ) 8. 编程的6个步骤中,如果在“输入测试数据,验证结果”时发现输出与预期不符,这通常说明发生了什么错误?
|
||||
A. 语法错误
|
||||
B. 逻辑错误
|
||||
C. 编译错误
|
||||
D. 硬件故障
|
||||
|
||||
( ) 9. 假如程序是 `int a; cin >> a;`,而用户输入了 `5 6` 然后按回车,那么变量 `a` 中存储的值是多少?
|
||||
A. 56
|
||||
B. 5
|
||||
C. 6
|
||||
D. 11
|
||||
|
||||
( ) 10. `int a, b; cin >> a >> b;` 这两行代码执行时,程序的行为是?
|
||||
A. 立刻计算 a+b 的值
|
||||
B. 在屏幕上输出 a 和 b
|
||||
C. 定义了两个变量,然后暂停等待用户输入两个由空白字符隔开的数据
|
||||
D. 定义了两个变量,然后程序直接结束
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
1. `cin` 的 `c` 代表 "C++",`in` 代表 "input"。 ( )
|
||||
2. 必须先定义变量,然后才能使用 `cin` 把数据存入这个变量。 ( )
|
||||
3. `cin` 使用的运算符是 `>>`,`cout` 使用的运算符是 `<<`,两者方向相反,作用也相反。 ( )
|
||||
4. `cin` 会自动忽略输入数据前多余的空格、Tab键或回车。 ( )
|
||||
5. 如果写 `cin >> x >> y;`,用户必须在同一行内输入两个数字,不能换行输入。 ( )
|
||||
6. “输入 -> 处理 -> 输出”是解决编程题目的三个基本步骤。 ( )
|
||||
7. 一个好的程序应该通过 `cin` 接收用户的任意合法输入,而不是每次都让用户去修改源代码。 ( )
|
||||
8. 在分析一个编程问题时,正确的做法是先动手写代码,再边写边想思路。 ( )
|
||||
9. `cin >> a;` 这行代码执行后,变量 `a` 的值就变成了用户刚刚从键盘输入的值。 ( )
|
||||
10. `cout >> "请输入一个数字";` 这行代码是正确的。 ( )
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,143 @@
|
||||
### **C++ 字符类型 `char` 与转义字符 讲义**
|
||||
|
||||
#### **第一部分:字符类型 `char` (存储单个字符的盒子)**
|
||||
|
||||
##### **1. 问题引入:除了数字,程序还能处理什么?**
|
||||
|
||||
在之前的学习中,我们已经学会了用 `int` 存储整数,用 `double` 存储小数。但我们的世界是由丰富多彩的文字和符号构成的。比如,我们要编写一个程序,实现一个简易计算器,用户会输入 `7 * 2` 这样的算式。
|
||||
* `7` 和 `2`,我们可以用 `int` 类型的变量来存储。
|
||||
* 但是中间的那个乘号 `*` 呢?它不是一个数字,我们该用什么类型的“盒子”来装它呢?
|
||||
|
||||
这时候,`char` 类型就登场了。
|
||||
|
||||
##### **2. 什么是 `char` 类型?**
|
||||
|
||||
`char` 是 "character" (翻译:字符) 的缩写。它是一种专门用来存放**单个字符**的数据类型。
|
||||
你可以把它想象成键盘上的**任意一个按键**,它可以是:
|
||||
|
||||
* 一个英文字母 (大写或小写): `'A'`, `'b'`, `'Z'`
|
||||
* 一个数字字符: `'0'`, `'1'`, `'9'` (注意:这和数字 `0, 1, 9` 是不同的)
|
||||
* 一个标点或符号: `','`, `'.'`, `'?'`, `'+'`, `'*'`
|
||||
* 一个空格: `' '`
|
||||
|
||||
##### **3. 如何在 C++ 中使用 `char`?**
|
||||
|
||||
`char` 的使用方式和 `int` 基本一致,但有一个**极其重要**的区别:
|
||||
|
||||
> **在为 `char` 变量赋值或进行比较时,字符值必须被一对单引号 `' '` 包围。**
|
||||
|
||||
* **正确的写法**:
|
||||
```cpp
|
||||
char c1 = 'A'; // 正确!用单引号包围
|
||||
char c2 = '*';
|
||||
char c3 = ' '; // 空格也是一个字符
|
||||
```
|
||||
* **错误的写法**:
|
||||
```cpp
|
||||
char c4 = A; // 错误!编译器会认为 A 是一个变量名,而不是字符'A'
|
||||
char c5 = "A"; // 错误!双引号 "" 是用来表示字符串的,不能用于单个字符
|
||||
```
|
||||
|
||||
##### **4. 实战演练:简易计算器**
|
||||
|
||||
* **问题**:输入两个整数和一个乘号 `*`,输出这两个整数的乘积。
|
||||
|
||||
* *输入样例*: `7 * 2`
|
||||
* *输出样例*: `14`
|
||||
* **逻辑分析**:
|
||||
|
||||
1. **准备“盒子”**:我们需要两个盒子装整数,一个盒子装中间的 `*` 号。
|
||||
* `int num1, num2;`
|
||||
* `char op;` (`op` 是 operator/操作符的英文缩写)
|
||||
2. **接收“原料”**:C++ 的 `cin` 非常智能,它会根据你变量的顺序和类型,自动读取并分割输入。
|
||||
* `cin >> num1 >> op >> num2;` 当用户输入 `7 * 2` 时,`cin` 会把 `7` 存入 `num1`,把 `*` 存入 `op`,把 `2` 存入 `num2`。
|
||||
3. **加工计算**:`int result = num1 * num2;`
|
||||
4. **交付产品**:`cout << result;`
|
||||
* **完整代码**:
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
int num1, num2;
|
||||
char op; // 准备一个char类型的盒子来装运算符
|
||||
|
||||
cout << "请输入一个乘法表达式 (如 7 * 2): ";
|
||||
cin >> num1 >> op >> num2;
|
||||
|
||||
int result = num1 * num2;
|
||||
cout << "计算结果是: " << result << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **第二部分:转义字符**
|
||||
|
||||
##### **1. 观察代码**
|
||||
|
||||
我们已经知道,放在双引号 `""` 里的内容,通常会被原样输出。但请观察以下代码:
|
||||
```cpp
|
||||
cout << "hello\nworld";
|
||||
```
|
||||
按照我们的直觉,屏幕上应该会打印出 `hello\nworld`。但实际运行结果却是:
|
||||
```
|
||||
hello
|
||||
world
|
||||
```
|
||||
|
||||
我们发现:
|
||||
1. 字符 `\` 和 `n` 在屏幕上“神秘地消失”了。
|
||||
2. `world` 被打印到了新的一行。
|
||||
|
||||
**原因解析**:这并不是 Bug,而是因为 `\n` 是 C++ 语法中的一个**转义字符。
|
||||
|
||||
##### **2. 转义字符的原理与应用**
|
||||
|
||||
* **什么是转义字符?**
|
||||
转义字符是一种特殊的符号组合,它以反斜杠 `\` 开头,用于在代码中表示一些**无法直接打印的控制功能**(如换行、制表符)或**具有特殊语法含义的字符本身**(如双引号、反斜杠自己)。
|
||||
|
||||
你可以把反斜杠 `\` 想象成一个“**魔法棒**”。当它出现在一个字符前面时,它会**改变**后面那个字符的本来面目,赋予它一个特殊的魔法效果。
|
||||
|
||||
* **常用转义字符对照表**
|
||||
| 转义符 | 术语 | 实际作用与说明 |
|
||||
| -------- | -------------- | ------------------------------------------------------------ |
|
||||
| **`\n`** | **换行符** | 效果:**换行**。将光标移动到下一行的行首。 |
|
||||
| **`\t`** | **水平制表符** | 效果:**对齐**。将光标向前跳跃一个制表位的距离(通常相当于几个空格)。 |
|
||||
| **`\\`** | **反斜杠字符** | 效果:让它变回一个普通的反斜杠字符并打印出来,即输出一个反斜杠本身。 |
|
||||
| **`\"`** | **双引号字符** | 效果:让它变回一个普通的双引号字符并打印出来,即输出一个双引号本身。 |
|
||||
| **`\'`** | **单引号字符** | 用于打印单引号本身。 |
|
||||
|
||||
##### **3. 综合应用实例**
|
||||
|
||||
* **任务目标**:在屏幕上输出下面这句话:
|
||||
|
||||
> `小明说:"what is \n"`
|
||||
|
||||
* **逻辑推演**:
|
||||
|
||||
1. **基础结构**:首先,整句话是一个字符串需要通过 `cout` 输出,那么需要用一对双引号包围。
|
||||
`cout << "小明说:"what is \n"";` <-- 如果这样直接写,就全部乱套了!
|
||||
2. **解决内部双引号冲突**:目标文本中的双引号 `"` 会让编译器误以为字符串提前结束了。我们需要用 `\"` 来告诉编译器:这个双引号只是一个普通字符,我想要输出它本身,不是字符串的边界。
|
||||
3. **解决 `\` 的冲突**:我们想输出 `\` 本身。于是我们需要用 `\\` 来打印出那个反斜杠本身。
|
||||
`cout << "小明说:\"what is \\n\"";` <-- 解决!
|
||||
|
||||
* **C++ 实现代码**:
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
cout << "小明说:\"what is \\n\"" << endl;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
#### **总结**
|
||||
|
||||
* **`char`** 是用来存储**单个**字符的“小盒子”,它的值必须用**单引号`''`**括起来。
|
||||
* **转义字符**以反斜杠 `\` 开头,它能赋予紧随其后的字符一个**特殊的功能**或让其**变回普通字符**。
|
||||
* `\n` (换行) 和 `\t` (制表) 是最常用的功能性转义字符。
|
||||
* 当你需要在字符串中打印 `"` 或 `\` 本身时,必须在它们前面再加上一个 `\`,即使用 `\"` 和 `\\`。
|
||||
Binary file not shown.
@@ -0,0 +1,142 @@
|
||||
# C++字符与 ASCII 码 讲义
|
||||
|
||||
## 1. 概念
|
||||
|
||||
在计算机的世界里,一切皆是 0 和 1(二进制)。计算机天生只认识数字,不认识字母、标点符号。
|
||||
为了让计算机能显示和处理文字,人类制定了一套规则:**给每一个字符指定一个唯一的数字编号**。
|
||||
|
||||
* **字符 (Character)**:我们在屏幕上看到的符号(如 `'A'`, `'@'`, `'1'`)。
|
||||
* **ASCII 码**:一种最基础的编码标准,规定了字符和数字之间的对应关系。
|
||||
|
||||
---
|
||||
|
||||
## 2. C++ 中的字符类型 (`char`)
|
||||
|
||||
在 C++ 中,我们学习了如何储存一个整数或者小数,但是字符是使用 `char` 关键字来定义并储存字符变量的。
|
||||
|
||||
### 2.1 基本语法
|
||||
* **书写方式**:必须使用**单引号** `' '` 括起来。
|
||||
* **本质**:`char` 类型在内存中实际上存储的是一个**整数**(即该字符对应的 ASCII 码值)。
|
||||
|
||||
```cpp
|
||||
char letter = 'A'; // 正确
|
||||
char numChar = '5'; // 正确,这是字符5,不是数字5
|
||||
// char error = "A"; // 错误!双引号代表字符串
|
||||
```
|
||||
|
||||
### 2.2 使用 `char`
|
||||
|
||||
**题目描述:请你实现普通计算器的功能,输入两个整数和一个*,输出这两个整数的乘积。**
|
||||
|
||||
**样例输入: 7 * 2**
|
||||
|
||||
**样例输出: 14**
|
||||
|
||||
---
|
||||
|
||||
**逻辑解析:**
|
||||
|
||||
- **定义容器**:我们需要两个 `int` 类型的变量来存放参与运算的数字,**以及一个 `char` 类型的变量来存放中间的运算符 `*`**,我们就可以定义:`int num1, num2; char ch; `
|
||||
|
||||
- **获取数据**:接受用户输入,将三个值分别放入三个变量中,并且按照顺序读取 `cin >> num1 >> ch >> num2;`
|
||||
|
||||
- **读取 `num1`**:读取的第一个是整数变量,于是`cin` 接着期待一个整数,例如它读取了 `7`,接着遇到了空格。所以它会**自动结束读取**,将 `7` 存入 `num1` 中。
|
||||
|
||||
- **读取 `op`**:接着是一个字符类型变量,于是`cin` 接着期待一个字符。拿到了字符 `*`,并存入字符变量 `op` 中。
|
||||
|
||||
- **读取 `num2`**:最后,`cin` 再次期待一个整数。它跳过空格,读取到数字 `2`,存入 `num2`。
|
||||
|
||||
- **计算结果:**`num1` 与 `num2` 已经存入了输入的两个整数,最后仅需按照题目要求输出这两个整数的乘积即可:`cout << num1 * num2;`
|
||||
|
||||
## 3. 什么是 ASCII 码?
|
||||
|
||||
**全称**:American Standard Code for Information Interchange(美国信息交换标准代码)。
|
||||
|
||||
因为计算机却只认识数字,不认识字符,那计算机怎么存储“Hello”这个单词呢?
|
||||
|
||||
为了解决这个问题,人类制定了一张**强制转换表**,这就是 **ASCII** **码表**。 它规定了每一个符号对应一个特定的整数。字符在计算机内部,本质上就是一个整数。
|
||||
|
||||
它是一张“对照表”,规定了 128 个字符对应的数字。
|
||||
|
||||
- 当你按下键盘上的 `A`。
|
||||
- 计算机查表:哦,`A` 对应的是 `65`。
|
||||
- 计算机存储:在内存里存下 `65` 。
|
||||
- 当你 `cout` 时:计算机读取 `65`,查表发现是 `A`,然后就输出一个 `A` 在屏幕上
|
||||
|
||||
### 3.1 ASCII 码表的构成
|
||||
1. **0 - 31 (控制字符)**:不可打印,用于控制外围设备,这部分**了解**即可,一般不会用到。
|
||||
* 例如在我们键盘上的:换行、回车、响铃、退格。
|
||||
2. **32 - 126 (可打印字符)**:键盘上能打出来的符号。
|
||||
* 包括:空格、标点、数字、大写字母、小写字母。**这部分需要知道掌握**。
|
||||
3. **127 (Delete)**:删除控制符,**了解**即可。
|
||||
|
||||
---
|
||||
|
||||
## 4. 必须记住的关键 ASCII 值
|
||||
|
||||
你不需要背诵整个表,但以下几个数值应当记住,因为它们常用于编程逻辑中。
|
||||
|
||||
| 字符类别 | 起始字符 | ASCII 值 | 结束字符 | ASCII 值 | 备注 |
|
||||
| :----------- | :------: | :------: | :------: | :------: | :-------------------------------- |
|
||||
| **数字** | `'0'` | **48** | `'9'` | **57** | 注意:`'0'` 和 `0` 不是同一个东西 |
|
||||
| **大写字母** | `'A'` | **65** | `'Z'` | **90** | |
|
||||
| **小写字母** | `'a'` | **97** | `'z'` | **122** | |
|
||||
|
||||
### 规律总结:
|
||||
1. 数字、大写字母、小写字母都是**连续**排列的。
|
||||
2. **大小写转换规律**:小写字母的 ASCII 值比对应的大写字母大 **32**。
|
||||
* `'a' - 'A' = 32`
|
||||
* `'A' + 32 = 'a'`
|
||||
|
||||
---
|
||||
|
||||
## 5. 字符与整数的互换 (C++ 的自动类型转换特性)
|
||||
|
||||
在 C++ 中,其实`char` 和 `int` 可以自由转换和运算。
|
||||
|
||||
1. 源类型向目标类型转换时。如果目标类型能够容纳源类型的值,且转换是安全的,编译器就会自动完成。
|
||||
- **例如**:`int` 赋给 `double` 是安全的(`int` 转换为 `double`)。
|
||||
- **但请注意:** `double` 赋给 `int` 时,虽然编译器会尝试转换(截断小数部分),但这通常被认为是**不安全的**,因为它会丢失精度。在严格的编译环境下可能会有警告,甚至在某些情况下需要显式转换(后续会讲解强制类型转化)。
|
||||
- **整型和浮点型混合运算时,整型会向浮点型转换以避免数据丢失**。**核心原则是** “向高精度、大范围类型转换”,以避免数据丢失。例如,`int` 和 `double` 相加时,`int` 会被转换为 `double`。
|
||||
|
||||
简单来说,C++的自动类型转换是尽力让你在不同类型之间进行操作时,得到一个合理的结果,并且尽量不丢失数据。
|
||||
|
||||
### 5.1 查看字符的 ASCII 码
|
||||
**使用 `int` 类型的变量来接住 `char` 类型的值。**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
char c = 'A';
|
||||
cout << "字符: " << c << endl; // 输出 A
|
||||
int num = c;
|
||||
cout << "ASCII值: " << num << endl; // 输出 65
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 字符运算 (算术操作)
|
||||
**因为字符本质是整数(通过ASCII码来进行对照),所以可以进行加减乘除。**
|
||||
|
||||
==**案例 1:大小写转换(重要,必须掌握)**==
|
||||
|
||||
利用小写与小写字符中的差值为 32 进行转化。
|
||||
|
||||
```cpp
|
||||
char upper = 'B';
|
||||
char lower = upper + 32; // 66 + 32 = 98 ('b')
|
||||
cout << lower << endl; // 输出 b
|
||||
```
|
||||
|
||||
==**案例 2:数字字符 转 整数数字**==
|
||||
这是算法题中非常常见的操作。因为数字字符在ASCII码里是连续的,所以任意一个 字符数字 和 字符0 之间的差值就是字符数字对应的整数数字。
|
||||
|
||||
例如`'7' - '0' = 7, '4' - '0' = 4, '0' - '0' = 0`。
|
||||
|
||||
```cpp
|
||||
char c_num = '8';
|
||||
int i_num = c_num - '0'; // '8'(56) - '0'(48) = 8
|
||||
cout << i_num << endl; // 输出数字 8
|
||||
```
|
||||
Binary file not shown.
@@ -0,0 +1,168 @@
|
||||
## **C++ 类型转换 讲义**
|
||||
|
||||
### 1. 引言
|
||||
|
||||
* **字符的储存**
|
||||
字符 `'A'` 在计算机底层又是用哪个数字存储的呢?计算机的本质是处理数字,我们看到的所有文本、字符,在它眼中都是一个个特定的数字。最著名的编码表就是 **ASCII** (美国信息交换标准代码),在书本P17页有部分的ASCII编码表可做参考。
|
||||
|
||||
### 2. 核心思想
|
||||
|
||||
**自动类型转换**
|
||||
我们有一个整数 `int number = 65;`。我们想得到它对应的字符。一个想法是:C++ 那么聪明,我直接把 `int` 赋值给 `char` 会怎么样?其实在 C++ 中,`char` 和 `int` 可以自由转换和运算。
|
||||
|
||||
```cpp
|
||||
int number = 65;
|
||||
char c = number; // C++ 允许这样做,它会自动转换
|
||||
cout << c; // 输出 'A'
|
||||
```
|
||||
|
||||
这种由编译器自动完成的转换,叫做 **自动类型转化(隐式转换)**。在很多简单场景下,它完全没有问题!但是,这种有时会隐藏一些问题。如果代码很复杂,**其他人读到 `char c = 65;` 时,可能会疑惑:这是一个笔误吗?还是故意这么写的?为什么两边的数据类型不一样?**
|
||||
|
||||
因为正常情况下,**赋值符号的右边的数据类型**应该和**左边的变量数据类型相匹配**。
|
||||
|
||||
但是有些情况也可以不一致。源类型向目标类型转换时(例子中 `char c = number;` 源类型就是 `int` , 目标类型是`char`)。如果源类型和目标类型不一致,**在编译器知道怎么转换的情况下,会进行自动类型转换!**
|
||||
|
||||
- **例如**:`int` 赋给 `double` 是安全的(`int` 转换为 `double`)。
|
||||
- **但请注意:** `double` 赋给 `int` 时,虽然编译器会尝试转换(截断小数部分),但这通常被认为是**不安全的**,因为它会丢失精度(小数点后的数据没有了)。
|
||||
- **整型和浮点型混合运算时,整型会向浮点型转换以避免数据丢失**。**核心原则是** “向高精度、大范围类型转换”,以避免数据丢失。例如,`int` 和 `double` 相加时,`int` 会被转换为 `double`。
|
||||
|
||||
==**简单来说,C++的自动类型转换是尽力让你在不同的数据类型之间进行操作时,得到一个合理的结果,并且尽量不丢失数据。**==
|
||||
|
||||
**强制类型转换(推荐使用!)**
|
||||
为了让我们的代码意图更加清晰,我们常常需要**强制类型转换**。
|
||||
|
||||
这相当于我们明确地告诉编译器:**我需要在这里把这个值的类型变一下!**
|
||||
|
||||
在 C++ 中,==强制类型转换语法==是:
|
||||
**`(目标类型) 变量名 或 数值`**
|
||||
|
||||
- 例1:要把变量 `int number` 转换为 `char` 类型,我们就可以写:`(char)number`。
|
||||
- 例2:要把变量 `int number` 转换为 `double` 类型,我们就可以写:`(double)number`。
|
||||
|
||||
**请注意:**如果我们想对 `a + b` 这种==**整个表达式的计算结果**==进行转换时,**就必须**使用括号 `()` 将表达式完整地包裹起来,写成 `(char)(a + b)`,以此来明确地告诉编译器:先算括号里的,再把算出来的最终结果进行转化!
|
||||
|
||||
而不能写成 `(char)a + b`,如果这样写,**它会先把变量 `a` 转换为 `char` 类型**。然后再去去和变量 `b` 相加。和我们的目的:将 `a + b` 的结果转化为 `char` 类型就不符了。
|
||||
|
||||
**步骤拆解**
|
||||
使用强制类型转换将数字转为字符的步骤很简单:
|
||||
|
||||
1. **准备一个整数**:定义一个 `int` 类型的变量,并存入一个在 ASCII 码范围内的数字。
|
||||
2. **执行转换**:使用 `(char)(你的整数变量)` 来进行转换。
|
||||
3. **存储结果**:将转换后的结果赋值给一个 `char` 类型的变量。
|
||||
4. **输出验证**:打印输出这个 `char` 变量,看看结果是否符合预期。
|
||||
|
||||
### 3. 实例
|
||||
|
||||
* **具体案例**
|
||||
让我们把数字 `97` 转换为它对应的 ASCII 字符。
|
||||
|
||||
* **分步演示**
|
||||
1. **准备一个整数**:
|
||||
```cpp
|
||||
int number = 97;
|
||||
```
|
||||
2. **执行转换**:我们使用强制类型转换。
|
||||
```cpp
|
||||
(char)number // 这个表达式的结果就是字符 'a'
|
||||
```
|
||||
3. **存储结果**:
|
||||
```cpp
|
||||
char res = (char)number;
|
||||
```
|
||||
4. **输出验证**:
|
||||
```cpp
|
||||
cout << res; // 屏幕上将会打印出 a
|
||||
```
|
||||
|
||||
### 4. 代码实现
|
||||
|
||||
现在,让我们把上面的步骤整合起来,写一个完整的程序。这个程序的作用是输入一个数字,输出这个数字在ASCII 码表中对应的字符。
|
||||
|
||||
* **完整代码**
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
cout << "请输入一个整数 (例如 65 到 90 之间): ";
|
||||
|
||||
// 定义变量并接收用户的输入
|
||||
int number;
|
||||
cin >> number;
|
||||
|
||||
// 使用强制类型转换
|
||||
// 将 int 类型的 number 转换为 char 类型
|
||||
char ascii_char = (char)number;
|
||||
|
||||
// 输出结果
|
||||
cout << "数字 " << number << " 在 ASCII 码表中对应的字符是: " << ascii_char << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 验证
|
||||
|
||||
让我们用几个例子来测试一下我们的程序,看看会发生什么。
|
||||
|
||||
* **正常情况**:
|
||||
* 输入 `65`,输出 `'A'`。
|
||||
* 输入 `97`,输出 `'a'`。
|
||||
* 输入 `48`,输出 `'0'`。
|
||||
* **常见问题**
|
||||
* **问**:为什么不直接用 `char c = number;`?
|
||||
* **答**:在简单情况下可以,但它属于自动类型转化转换,意图不明确。像 `(char)number` 这样的强制转换,能让你的代码意图更清晰,一眼就能让人知道你是故意这样做的。
|
||||
* **问**:强制类型转换安全吗?
|
||||
* **答**:不一定。比方说: `double` 强制转换为 `int` 类型时,虽然编译器会转换(但是会截断小数部分)。所以,在转换前你要对数据的范围有的认识。例如你想转化一个整数到`char`字符类型,那就要确保这个整数的数值在ASCII码表中有对应的字符,如果这个数字根本不存在对应的字符,那计算机就也不知道应该如何转化了。
|
||||
|
||||
---
|
||||
|
||||
### **6. C++ 字符大小写转换(两种办法)**
|
||||
|
||||
#### 一:直接观察法
|
||||
|
||||
* 观察 ASCII 码表,你会发现一个规律:
|
||||
|
||||
* `'A'` 是 65, `'a'` 是 97
|
||||
* `'B'` 是 66, `'b'` 是 98
|
||||
* ...
|
||||
* `'Z'` 是 90, `'z'` 是 122
|
||||
|
||||
**任意一个相同字母的小写形式,其 ASCII 码值都比大写形式大 32!** (`'a' - 'A' = 97 - 65 = 32`)
|
||||
|
||||
基于这个规律,我们有实现方式:
|
||||
|
||||
* **==小写转大写==**:`大写字符 = 小写字符 - 32`
|
||||
* **==大写转小写==**:`小写字符 = 大写字符 + 32`
|
||||
* **案例:大小写转换**
|
||||
|
||||
```cpp
|
||||
char upper = 'B';
|
||||
char lower = upper + 32; // 66 + 32 = 98 ('b')
|
||||
cout << lower; // 输出 b
|
||||
```
|
||||
|
||||
#### **二:差值计算法**:
|
||||
|
||||
例如想要将大写字符 `'C'`转为小写
|
||||
|
||||
1. **计算偏移量**:首先,我们需要知道目标字母 `'C'` 相对于大写字母起点 `'A'` 的“位置”或“差值量”。
|
||||
* 这个偏移量可以通过减法计算得出:`'C' - 'A'`。我们知道结果是 `2`。这告诉我们,`'C'` 是排在 `'A'` 后面的第2个字母(从0开始计数)。
|
||||
|
||||
2. **找到新起点**:我们的目标是小写字母,那么小写字母的“起点”是谁?是 `'a'`。
|
||||
|
||||
3. **应用偏移量**:我们在新的起点 `'a'` 上,加上刚才计算出的差值量 `2`,就能得到我们想要的小写字母。
|
||||
* `'a' + ('C' - 'A')`
|
||||
* `'a' + 2` --> 结果就是 `'c'`。
|
||||
|
||||
* **公式**:
|
||||
* **大写转小写**:`小写字母 = 任意大写字母 - 'A' + 'a'`
|
||||
* **小写转大写**:`大写字母 = 任意小写字母 - 'a' + 'A'`
|
||||
|
||||
### 总结
|
||||
|
||||
1. 字符在计算机底层是以数字(如 ASCII 码)存储的。
|
||||
2. `char` 和 `int` 之间可以相互转换。
|
||||
3. 使用 `(目标类型)值` 的形式可以进行**强制类型转换**,这能让代码的意图更清晰。
|
||||
4. 进行类型转换时,要注意目标类型的**取值范围**,防止数据**溢出**,例如你想转化一个整数到`char`字符类型,那就要确保这个整数的数值在ASCII码表中有对应的字符,如果这个数字根本不存在对应的字符,那计算机就也不知道应该如何转化了。
|
||||
5. 英文字母的大小写形式在 ASCII 码表中具有固定的数值差 (`32`)。
|
||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
### **C++ 转义字符与字符类型 课后习题 - 答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `char`
|
||||
2. 单引号
|
||||
3. `100`
|
||||
4. `\\`
|
||||
5. `\"Hi\"`
|
||||
6. `':'`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **C**. `char` 类型的字面量必须用单引号包裹,且只能是单个字符。
|
||||
2. **C**. `\n` 是换行符,会让 `Tom` 显示在下一行。
|
||||
3. **B**. 反斜杠 `\` 本身是转义字符,要输出它自身,需要写成 `\\`。
|
||||
4. **A**. `cin` 会依次读取一个整数存入 `a`,一个字符存入 `op`,一个整数存入 `b`。输入 `5+3` 时,`op` 会接收到字符 `'+'`。
|
||||
5. **B**. `\"` 是双引号的转义序列,用于在字符串内部表示一个双引号字符。
|
||||
6. **D**. `char` 变量只能存放单个字符,`'Go'` 包含两个字符,是错误的。
|
||||
7. **A**. 程序读取一个整数 `h`,然后需要读取一个字符,最后读取一个整数 `m`。
|
||||
8. **C**. `\\` 是 `\` 的转义序列,所以 `\\` 会让 `\` 失去转义功能,变回它本身。因此 `\\n` 会输出 `\n` 这两个字符。
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. × (必须用单引号 `' '`。)
|
||||
2. √ (两者最终在屏幕上看到的换行效果是一样的。)
|
||||
3. √ (`cin` 默认通过空白字符(空格、回车等)分隔数据,读到 'A' 后遇到空格,就完成了对 `c` 的读取。)
|
||||
4. √ (这正是转义字符的定义。)
|
||||
5. × ( `char` 只能存放单个字符。)
|
||||
6. √ (`cin` 会先读取数字部分 `99` 存入 `a`,然后接着读取非数字字符 `'A'` 存入 `c`。)
|
||||
7. √ ( `"` 是特殊字符,在字符串中必须通过 `\"` 来表示。)
|
||||
8. √ (如 `cin >> a >> op >> b;` 所示,`cin` 可以很灵活地连续读取不同类型的数据。)
|
||||
Binary file not shown.
@@ -0,0 +1,78 @@
|
||||
### **C++ 转义字符与字符类型 课后习题**
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. C++中,用于存放单个字符(如 'A', '?')的数据类型是 \_\_\_\_\_\_\_\_\_\_。
|
||||
2. 在为 `char` 类型变量赋值时,该字符必须被一对 \_\_\_\_\_\_\_\_\_\_(填“单引号”或“双引号”)包围。
|
||||
3. 代码 `cout << "Score:\n100";` 的输出结果是:第一行显示 `Score:`,第二行显示 \_\_\_\_\_\_\_\_\_\_。
|
||||
4. 如果想在屏幕上显示出路径 `D:\Data`,那么在代码的字符串中应该写作 `D:________Data`。
|
||||
5. 如果想在屏幕上显示出带引号的文字 `He said: "Hi"`,那么代码中表示 `"Hi"` 的部分应该写作 \_\_\_\_\_\_\_\_\_\_。
|
||||
6. 对于代码 `int h; char c; cin >> h >> c;`,如果用户输入 `12:59` 并回车,那么整型变量 `h` 的值是 `12`,而字符型变量 `c` 的值是 \_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 下面哪个是定义 `char` 变量并正确赋值的语句?
|
||||
A. `char c = "A";`
|
||||
B. `char c = A;`
|
||||
C. `char c = 'A';`
|
||||
D. `char c = 'AB';`
|
||||
|
||||
( ) 2. 执行 `cout << "Name:\nTom";` 后,屏幕上会显示什么?
|
||||
A. `Name:\nTom`
|
||||
B. `Name: Tom`
|
||||
C. 两行,第一行 `Name:`,第二行 `Tom`
|
||||
D. `Name:Tom`
|
||||
|
||||
( ) 3. 哪句代码可以在屏幕上正确输出路径 `C:\` ?
|
||||
A. `cout << "C:\";`
|
||||
B. `cout << "C:\\";`
|
||||
C. `cout << "C:/";`
|
||||
D. `cout << 'C:\';`
|
||||
|
||||
( ) 4. 阅读以下代码,如果用户输入 `5+3` 并回车,变量 `op` 的值是多少?
|
||||
```cpp
|
||||
int a, b;
|
||||
char op;
|
||||
cin >> a >> op >> b;
|
||||
```
|
||||
A. `'+'`
|
||||
B. `+`
|
||||
C. `" "` (空格)
|
||||
D. 程序会报错
|
||||
|
||||
( ) 5. 执行 `cout << "He said \"Go!\"";` 后,屏幕上会显示什么?
|
||||
A. `He said Go!`
|
||||
B. `He said "Go!"`
|
||||
C. `He said \"Go!\"`
|
||||
D. `He said: "Go!"`
|
||||
|
||||
( ) 6. 以下哪个**不能**被正确地赋值给一个 `char` 类型的变量?
|
||||
A. `'?'`
|
||||
B. `' '`
|
||||
C. `'7'`
|
||||
D. `'Go'`
|
||||
|
||||
( ) 7. 有代码 `int h, m; char c; cin >> h >> c >> m;`,为了让程序成功读入小时 `11` 和分钟 `59`,不正确的输入格式是?
|
||||
A. `11 59`
|
||||
B. `11:59`
|
||||
C. `11,59`
|
||||
D. `11;59`
|
||||
|
||||
( ) 8. 执行 `cout << "\\n";` 后,屏幕上会显示什么?
|
||||
A. 一个空行
|
||||
B. `n`
|
||||
C. `\n`
|
||||
D. `\`
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. 在C++中,定义一个字符变量时,字符必须用双引号 `"` 包起来。
|
||||
( ) 2. `\n` 和 `endl` 都能在 `cout` 中实现换行的视觉效果。
|
||||
( ) 3. 对于 `char c; cin >> c;`,如果用户输入 `A B` 并回车,变量 `c` 的值会是 `'A'`。
|
||||
( ) 4. 转义字符 `\` 本身通常不会被显示,它的作用是改变其后字符的含义。
|
||||
( ) 5. 一个 `char` 类型的变量可以存放一个单词,比如 `'Hello'`。
|
||||
( ) 6. 对于 `int a; char c; cin >> a >> c;`,如果用户输入 `99A`,那么 `a` 的值是 `99`,`c` 的值是 `'A'`。
|
||||
( ) 7. 想输出双引号 `"`,代码必须写成 `cout << "\"";`。
|
||||
( ) 8. `cin` 可以一次性读取不同类型的变量,例如 `int` 和 `char`。
|
||||
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
### 参考答案
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `char`
|
||||
2. 单引号
|
||||
3. `66`
|
||||
4. `32`
|
||||
5. `5`
|
||||
6. `'+'`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. C
|
||||
2. C
|
||||
3. B (字符'C'的ASCII码是67,加1后是68,68对应的字符是'D')
|
||||
4. B
|
||||
5. B
|
||||
6. A
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. × (一个是字符,一个是数字,它们的ASCII码和数值都不同)
|
||||
2. √
|
||||
3. √
|
||||
4. × (从'A'到'Z',ASCII码是递增的)
|
||||
5. √
|
||||
6. × (`char` 只能存放单个字符)
|
||||
Binary file not shown.
@@ -0,0 +1,70 @@
|
||||
### C++ 字符与 ASCII 码 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 在 C++ 中,我们使用关键字 \_\_\_\_\_\_\_\_ 来定义一个存放单个字符的变量。
|
||||
|
||||
2. 定义一个字符变量时,字符本身必须用 \_\_\_\_\_\_\_\_ (填“单引号”或“双引号”) 括起来。
|
||||
|
||||
3. 字符 `'A'` 对应的 ASCII 码值是 `65`,那么字符 `'B'` 对应的 ASCII 码值是 \_\_\_\_\_\_\_\_。
|
||||
|
||||
4. 小写字母 `'a'` 的 ASCII 码值比大写字母 `'A'` 的 ASCII 码值大 \_\_\_\_\_\_\_\_。
|
||||
|
||||
5. 阅读代码 `char c = '5'; int n = c - '0';`,执行后,整型变量 `n` 中存放的值是 \_\_\_\_\_\_\_\_。
|
||||
|
||||
6. 在 `cin >> num1 >> op >> num2;` 中,如果用户输入 `10 + 20`,那么字符变量 `op` 中存入的值是 \_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 下列哪个是**正确**的字符变量定义语句?
|
||||
A. `char c = "A";`
|
||||
B. `char c = A;`
|
||||
C. `char c = 'A';`
|
||||
D. `int c = 'A';`
|
||||
|
||||
( ) 2. 执行 `int ch = 'a'; cout << ch;` 后,屏幕上会显示什么?
|
||||
A. `a`
|
||||
B. `A`
|
||||
C. `97`
|
||||
D. `65`
|
||||
|
||||
( ) 3. 阅读以下代码:
|
||||
```cpp
|
||||
char letter = 'C';
|
||||
letter = letter + 1;
|
||||
cout << letter;
|
||||
```
|
||||
程序的输出结果是?
|
||||
A. `C`
|
||||
B. `D`
|
||||
C. `67`
|
||||
D. `68`
|
||||
|
||||
( ) 4. 如果想把大写字母 `'E'` 转换为对应的小写字母,正确的代码是?
|
||||
A. `'E' - 32`
|
||||
B. `'E' + 32`
|
||||
C. `'E' - 'A'`
|
||||
D. `'E' + 'a'`
|
||||
|
||||
( ) 5. 在计算机内部,`char` 类型的变量实际上存放的是什么?
|
||||
A. 字符的形状
|
||||
B. 字符对应的 ASCII 码(一个整数)
|
||||
C. 一段文字
|
||||
D. 一个小数
|
||||
|
||||
( ) 6. `int a; char op; cin >> a >> op;` 如果用户输入 `9*`,那么变量 `a` 和 `op` 的值分别是?
|
||||
A. `a` 是 `9`,`op` 是 `'*'`
|
||||
B. `a` 是 `'9'`,`op` 是 `'*'`
|
||||
C. `a` 是 `9`,`op` 的值不确定
|
||||
D. 读取会失败
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. 在 C++ 中,字符 `'8'` 和整数 `8` 是完全一样的。
|
||||
( ) 2. 计算机能识别和处理文字,是因为有一张像 ASCII 码这样的“字符-数字”对照表。
|
||||
( ) 3. 数字字符是连续排列的,例如 `'1'` 的 ASCII 码比 `'0'` 的大 1。
|
||||
( ) 4. 大写字母 `'Z'` 的 ASCII 码比 `'A'` 的小。
|
||||
( ) 5. 因为字符本质上是数字,所以我们可以对 `char` 类型的变量进行加减运算。
|
||||
( ) 6. `char c = 'ab';` 这样的写法是正确的。
|
||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
### C++ 类型转换 课后习题 - **答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. ASCII
|
||||
2. 自动类型
|
||||
3. 强制类型
|
||||
4. 目标类型
|
||||
5. 32
|
||||
6. `(a + b)`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. B 2. C 3. A 4. B 5. B 6. C 7. C 8. B 9. C 10. C
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. × (保存的是对应的数字,即ASCII码)
|
||||
2. × (这是自动类型转换/隐式转换)
|
||||
3. √
|
||||
4. √
|
||||
5. × (会丢失小数部分,是不安全的操作)
|
||||
6. × (前者先转换x再加y,后者先算x+y再转换结果)
|
||||
7. √
|
||||
8. × (转换前需要了解数据范围,否则可能得到预期外的结果)
|
||||
9. √
|
||||
10. √
|
||||
@@ -0,0 +1,65 @@
|
||||
### C++ 类型转换 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 计算机在存储字符(如 `'A'`)时,实际上存的是一个数字,这个数字是根据 \_\_\_\_\_\_\_\_\_\_\_\_\_ 码表来确定的。
|
||||
2. 例如`int a = 'A';`赋值符两边的类型不一致的情况,会由编译器完成类型转换,叫做 \_\_\_\_\_\_\_\_\_\_\_\_\_ 转换。
|
||||
3. 为了让代码的意图更清晰,我们通过 `(目标类型)变量名/数值` 的格式去进行类型类型的方式,叫做 **\_\_\_\_\_\_\_\_\_\_\_\_\_**转换。
|
||||
4. 强制类型转换的语法格式是:`(`\_\_\_\_\_\_\_\_\_\_\_\_\_`)变量名/数值`。
|
||||
5. 根据ASCII码表的规律,任意一个大写英文字母和它对应的小写字母,它们对应的数字相差 \_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
6. 要把一个表达式 `a + b` 的计算**结果**整体转换为 `char` 类型,正确的写法是 `(char)`\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 执行 `cout << (char)65;` 这行代码,屏幕上会输出什么?
|
||||
A. 65 B. 'A' C. 'a' D. 无法输出
|
||||
|
||||
( ) 2. 执行 `cout << (int)'a';` 这行代码,屏幕上会输出什么?
|
||||
A. 'a' B. 65 C. 97 D. 32
|
||||
|
||||
( ) 3. 要将大写字母 `'C'` 转换为小写字母 `'c'`,正确的计算方法是?
|
||||
A. `'C' + 32` B. `'C' - 32` C. `'C' + 'a'` D. `'C' - 'A'`
|
||||
|
||||
( ) 4. 要将小写字母 `'z'` 转换为大写字母 `'Z'`,正确的计算方法是?
|
||||
A. `'z' + 32` B. `'z' - 32` C. `'z' + 'A'` D. `'z' - 'a'`
|
||||
|
||||
( ) 5. 当一个 `double` 类型的变量(如 `3.14`)被转换为 `int` 类型时,会发生什么?
|
||||
A. 四舍五入,变为 3
|
||||
B. 丢失小数部分,变为 3
|
||||
C. 四舍五入,变为 4
|
||||
D. 程序会报错
|
||||
|
||||
( ) 6. 表达式 `(char)('B' + 1)` 的计算结果是什么?
|
||||
A. 'B' B. 'A' C. 'C' D. 2
|
||||
|
||||
( ) 7. 相比于 `char c = 97;`,使用 `char c = (char)97;` 这种写法的优点是?
|
||||
A. 运行速度更快
|
||||
B. 程序占用的内存更小
|
||||
C. 代码的意图更清晰明确
|
||||
D. 没有任何区别
|
||||
|
||||
( ) 8. 差值计算法中,`'D' - 'A'` 这个表达式的含义是?
|
||||
A. 字母D减去字母A
|
||||
B. 计算D和A的ASCII码值的差
|
||||
C. 这是一个错误写法
|
||||
D. 结果等于 `'C'`
|
||||
|
||||
( ) 9. 当一个 `int` 类型的数和一个 `double` 类型的数做加法时,`int` 类型会自动转换为哪个类型?
|
||||
A. `char` B. `int` C. `double` D. 不会转换
|
||||
|
||||
( ) 10. `cout << (char)48;` 会在屏幕上输出什么字符?
|
||||
A. 'a' B. 'A' C. '0' D. '1'
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
( ) 1. 计算机在保存字符 `'A'` 时,就是保存了字母A的图片信息。
|
||||
( ) 2. `char c = 65;` 这种写法属于强制类型转换。
|
||||
( ) 3. 在ASCII码表中,所有小写字母对应的数字都比对应的大写字母要大。
|
||||
( ) 4. 表达式 `'a' - 'A'` 的计算结果是 `32`。
|
||||
( ) 5. 把一个小数(`double`)赋值给一个整数(`int`)是一种安全的操作,不会丢失任何数据。
|
||||
( ) 6. `(char)x + y` 和 `(char)(x + y)` 的计算过程和结果是完全一样的。
|
||||
( ) 7. `'Y' + 32` 的计算结果是小写字母 `'y'`。
|
||||
( ) 8. 使用 `(char)num` 进行强制类型转换前,我们不需要关心 `num` 的值是多少,转换总是安全的。
|
||||
( ) 9. `'a' + ('C' - 'A')` 这个表达式可以把大写字母 `'C'` 转换为小写字母 `'c'`。
|
||||
( ) 10. 字符不仅可以和数字进行转换,字符之间也可以进行加减运算。
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,283 @@
|
||||
### **C++ 格式化输入与输出 讲义**
|
||||
|
||||
#### **一、 引言**
|
||||
|
||||
##### **问题引入:数字反转**
|
||||
|
||||
【书本P21页 例2-7】我们来看一个问题:
|
||||
> 输入一个三位浮点数,例如 `123.4`,要求把这个数字彻底翻转过来,变成 `4.321` 并输出。
|
||||
|
||||
乍一看,这个问题似乎很难下手。我们熟悉的 `cin` 只能整个地读取这个数字,`cout` 也只能整个地输出。我们如何能把——`1`、`2`、`3`、`.`、`4`——拆开,再按新的顺序重新组合呢?
|
||||
|
||||
---
|
||||
|
||||
#### **二、 解法一:数学运算**
|
||||
|
||||
在揭晓新工具之前,我们先用已有的知识尝试解决。
|
||||
|
||||
##### **思路铺垫**
|
||||
|
||||
对于 `123.4`,最碍事的就是那个小数点。如果我们能先把它变成整数 `1234`,问题就简化成了“整数拆分”。
|
||||
|
||||
##### **核心工具:提取器与削减器**
|
||||
|
||||
我们回顾一下拆分整数的两个工具:
|
||||
|
||||
1. **个位的提取器 (`% 10`)**
|
||||
* **作用**:获取一个整数的**最右边一位**。
|
||||
* **原理**:任何整数除以10的**余数**,正好就是它的个位数。
|
||||
* **示例**:`1234 % 10` 结果是 `4`。
|
||||
|
||||
2. **数字的削减器 (`/ 10`)**
|
||||
* **作用**:**砍掉**一个整数的**最右边一位**。
|
||||
* **原理**:在C++中,`整数 / 整数` 的结果会**直接舍弃小数部分**。
|
||||
* **示例**:`1234 / 10` 结果是 `123`。
|
||||
|
||||
##### **步骤拆解**
|
||||
|
||||
1. **第一步(提取)**:使用 **提取器 (`% 10`)** 获得当前数字的个位数。
|
||||
2. **第二步(削减)**:使用 **削减器 (`/ 10`)** 砍掉个位数,得到一个更小的数,为下一次操作做准备。
|
||||
|
||||
---
|
||||
|
||||
**具体案例**
|
||||
|
||||
让我们来手动拆解整数 `479`。
|
||||
|
||||
**分步演示**:
|
||||
|
||||
* **初始状态**: 我们有一个整数 `n = 479`。
|
||||
|
||||
* **第一轮操作 (处理 `479`)**:
|
||||
|
||||
1. **提取**: `479 % 10` -> 我们得到了数字 **`9`**。
|
||||
2. **削减**: `479 / 10` -> `n` 现在变成了 **`47`**。
|
||||
|
||||
* *我们成功地把 `9` 从 `479` 中分离了出来,并且得到了一个更简单的问题:如何拆解 `47`。*
|
||||
|
||||
* **第二轮操作 (处理 `47`)**:
|
||||
|
||||
1. **提取**: `47 % 10` -> 我们得到了数字 **`7`**。
|
||||
2. **削减**: `47 / 10` -> `n` 现在变成了 **`4`**。
|
||||
|
||||
* *小结:我们又分离出了 `7`,问题变得更简单了:如何拆解 `4`。*
|
||||
|
||||
* **第三轮操作 (处理 `4`)**:
|
||||
|
||||
1. **提取**: `4 % 10` -> 我们得到了数字 **`4`**。
|
||||
2. **削减**: `4 / 10` -> `n` 现在变成了 **`0`**。
|
||||
|
||||
* *小结:我们分离出了最后的 `4`,`n` 变成了 `0`,说明拆解工作已全部完成!*
|
||||
|
||||
而对于我们的题目:**输入一个三位浮点数,例如 `123.4`,要求把这个数字彻底翻转过来,变成 `4.321` 并输出。**
|
||||
|
||||
我们就也能通过整数拆分的办法来解决了。
|
||||
|
||||
1. **预处理**:`double num = 123.4; int n = num * 10;` -> 得到整数 `1234`。
|
||||
2. **逐位拆分**:
|
||||
* `int d = n % 10;` // d = 4
|
||||
* `int c = (n / 10) % 10;` // c = 3
|
||||
* `int b = (n / 100) % 10;` // b = 2
|
||||
* `int a = n / 1000;` // a = 1
|
||||
3. **重新组合输出**:
|
||||
* `cout << d << "." << c << b << a;`
|
||||
|
||||
**结论**:通过整数拆分的方法可以解决本问题,且一定要掌握通过数学运算拆分整数的办法。
|
||||
|
||||
---
|
||||
|
||||
#### **常见问题**
|
||||
|
||||
1. **问:对一个个位数(比如 `8`)使用这两个工具会怎样?**
|
||||
* **答**:完全符合规则,不会出问题!
|
||||
* **提取器**:`8 % 10` 的结果是 `8`。(8除以10,商0余8,成功提取出了最后一位数字 8)
|
||||
* **削减器**:`8 / 10` 的结果是 `0`。(8除以10,整数商是0,成功削减了最后一位数字 8)
|
||||
2. **问:如果数字里有 `0` 呢?比如 `205`?**
|
||||
* **答**:规则同样适用!
|
||||
* **第一轮**: `205 % 10` -> `5`;`205 / 10` -> `20`。
|
||||
* **第二轮**: `20 % 10` -> `0`;`20 / 10` -> `2`。
|
||||
* **第三轮**: `2 % 10` -> `2`;`2 / 10` -> `0`。
|
||||
|
||||
---
|
||||
|
||||
#### **要点回顾**
|
||||
|
||||
1. **个位的提取器 (`% 10`)**:它的作用就是帮你**看到并取走**一个整数最右边的那一位。
|
||||
2. **数字的削减器 (`/ 10`)**:它的作用就是**砍掉**一个整数最右边的那一位,让数字变小。
|
||||
3. 而且“提取”后必须“削减”,这样才能为处理下一位数字做准备。它们总是成对出现。
|
||||
|
||||
---
|
||||
|
||||
#### **三、 `printf` **
|
||||
|
||||
##### **核心概念与语法**
|
||||
|
||||
`printf` 的全称是 **Print Formatted(格式化打印)**。
|
||||
它的作用是:**先写好一段带有“空位”的模板句子,然后再把变量按顺序填入这些空位中。**
|
||||
|
||||
**语法格式:**
|
||||
|
||||
> `printf("包含格式说明符(占位符)的字符串", 变量1, 变量2, ...);`
|
||||
|
||||
##### **`printf` 的使用方法**
|
||||
|
||||
1. **打印纯文本**
|
||||
|
||||
```cpp
|
||||
printf("Hello, World!\n"); // \n 代表换行
|
||||
```
|
||||
|
||||
2. **打印单个变量**
|
||||
`printf` 在于用**格式说明符**(以`%`开头的占位符)去指定“空位”的类型,也就是先挖个坑占个座,之后我来告诉你什么数据会放在这里你进行输出就可以了。
|
||||
|
||||
```cpp
|
||||
int age = 30;
|
||||
// %d 是专门用来放整数的占位符
|
||||
printf("我的年龄是 %d 岁。\n", age);
|
||||
```
|
||||
**逻辑解释:**
|
||||
|
||||
1. `"我的年龄是%d岁。\n"` 是输出的模板字符串。
|
||||
2. `%d` 是一个占位符。
|
||||
3. `printf` 会在输出时,自动按照顺序用后面 `age` 变量的值(30)去替换 `%d` 的位置。
|
||||
|
||||
3. **混合打印多个变量**
|
||||
|
||||
`printf` 也可以极其方便地在一句话中同时输出多个、多种类型的变量,而不需要像 `cin` 或 `cout` 那样反复使用 `<<` 拼接。
|
||||
|
||||
```cpp
|
||||
int age = 15;
|
||||
double height = 168.5;
|
||||
char rank = 'S';
|
||||
|
||||
// 依次使用 %d, %lf, %c 作为占位符
|
||||
printf("我今年%d岁,身高是%lf厘米,综合评级:%c\n", age, height, rank);
|
||||
```
|
||||
**核心规则**:
|
||||
|
||||
* **一一对应:** 字符串里有 3 个坑(`%d`, `%lf`, `%c`),后面就必须跟着 3 个变量(`age`, `height`, `rank`)。
|
||||
* **按顺序入座:** `printf` 会严格按照从左到右的顺序,把第一个变量填入第一个占位符,第二个变量填入第二个占位符,以此类推。
|
||||
* **类型必须匹配:** 第一个是整数类型 `age`,所以必须用 `%d`;第二个是小数类型 `height`,必须用 `%lf/%f`;第三个是字符类型 `rank`,必须用 `%c`。
|
||||
|
||||
##### **常用格式说明符(书本P24页,重要!)**
|
||||
|
||||
占位符的顺序必须与后面变量的顺序一一对应,且数据类型必须兼容!
|
||||
|
||||
| 占位符 | 对应数据类型 | 说明 |
|
||||
| ---------- | -------------- | ------------------------------------------------------------ |
|
||||
| **`%d`** | `int` | 打印整数 |
|
||||
| **`%f`** | `float`、`double` | 打印浮点数 (默认保留6位小数) |
|
||||
| **`%lf`** | `float`、`double` | 输出时与 `%f` 相同;小数位数由精度指定 |
|
||||
| **`%c`** | `char` | 打印单个字符 |
|
||||
| **`%.mf`** | `float/double` | **技巧:** 打印浮点数,并**精确保留m位小数**。例如 `%.2f` 就是保留两位。 |
|
||||
|
||||
### `cout` 与 `printf` 写法对比
|
||||
|
||||
| 操作目标 | `cout` 写法 | `printf` 写法 |
|
||||
| ---------------- | ------------------------------- | ------------------------------- |
|
||||
| 打印纯文本 | `cout << "输出的内容";` | `printf("输出的内容");` |
|
||||
| 打印单个变量 | `cout << num1;` | `printf("%d", num1);` |
|
||||
| 混合打印多个变量 | `cout << num1 << "和" << num2;` | `printf("%d和%d", num1, num2);` |
|
||||
|
||||
---
|
||||
|
||||
#### **四、 `scanf` **
|
||||
|
||||
##### **概念与语法**
|
||||
|
||||
`scanf` 的全称是 **Scan Formatted(格式化扫描/输入)**。
|
||||
它的逻辑和 `printf` 基本一致,只不过从输出数据 变成了 输入数据:它会根据你提供的格式字符串模板,去键盘的输入中**抓取**对应的数据。
|
||||
|
||||
**语法格式:**
|
||||
|
||||
> `scanf("格式控制字符串", &变量1, &变量2, ...);`
|
||||
|
||||
##### **要注意 `scanf` 必须加 `&`(取地址符)**
|
||||
|
||||
**原理:**
|
||||
|
||||
* `cin` 很智能,你告诉它抽屉的名字(如 `age`),它就能自己找到。
|
||||
* `scanf` 是一位老员工,你必须把这个抽屉在内存中的**具体物理地址**交给它,它才能把数据放进去。
|
||||
|
||||
那么在变量名前加上 `&`,就相当于提取了这个变量的地址,所以这个符号也被称为取地址符!
|
||||
|
||||
> **警告:** 如果忘记写 `&`,程序在运行到输入阶段时会直接崩溃!
|
||||
|
||||
**基础使用示例:**
|
||||
|
||||
```cpp
|
||||
int age;
|
||||
printf("请输入您的年龄:");
|
||||
scanf("%d", &age); // 从键盘输入获取一个整数,存入 age 所在的内存地址
|
||||
// 现在 age 中就储存了输入的数据
|
||||
```
|
||||
|
||||
##### **`scanf` 的使用技巧**
|
||||
|
||||
1. **一次性读取多个数据**
|
||||
```cpp
|
||||
int a;
|
||||
double b;
|
||||
scanf("%d%lf", &a, &b); // 从键盘输入中读取一个整数和一个double类型的数据
|
||||
```
|
||||
*用户输入时用空格、Tab或回车 (空白字符) 隔开即可,`scanf` 会自动跳过它们。*
|
||||
|
||||
2. **易错点:不要在格式字符串里乱加标点,除非题目格式明确要求了**
|
||||
|
||||
* **错误写法**:`scanf("%d,%d", &a, &b);`
|
||||
* **后果**:那么用户输入时**必须严格**按照格式输入:**[一个整数 逗号 一个整数]** 的格式,例如`5, 10` 。如果不带逗号输入`[5 10]`的话就会读取失败。
|
||||
* **正确、安全的写法**:`scanf("%d%d", &a, &b);` 保持格式字符串的干净,只保留占位符。
|
||||
|
||||
---
|
||||
|
||||
#### **五、 实战演练**
|
||||
|
||||
##### **实战1:数字反转**
|
||||
|
||||
**解题思路**:我们不把 `123.4` 看作数字,而是看作“3个字符 + 1个小数点 + 1个字符”。利用 `scanf` 的格式匹配能力,将它们分离到不同的`char`变量中!
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
|
||||
int main() {
|
||||
char a, b, c, d;
|
||||
// 输入格式为 %c%c%c.%c,匹配 [字符 字符 字符 小数点 字符] 的格式将4个字符分离出来
|
||||
scanf("%c%c%c.%c", &a, &b, &c, &d);
|
||||
|
||||
// 按照 d.cba 的倒序格式输出
|
||||
printf("%c.%c%c%c\n", d, c, b, a);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
*用 `scanf` 和 `printf`问题就会变得非常简单!*
|
||||
|
||||
##### **实战2:再分肥宅水(书本P23页)**
|
||||
|
||||
**题目要求**:$t$ 毫升水均分给 $n$ 名同学。输出每人获得多少毫升(严格保留3位小数)以及一共需要多少个杯子(每人2个)。
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
|
||||
int main() {
|
||||
double t;
|
||||
int n;
|
||||
|
||||
// 用 %lf 读 double, 用 %d 读 int
|
||||
scanf("%lf%d", &t, &n);
|
||||
|
||||
// t/n 对应 %.3f (保留三位小数), n*2 对应 %d,中间用 \n 换行
|
||||
printf("%.3f\n%d\n", t / n, n * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **六、 总结**
|
||||
|
||||
* `cin/cout`:语法简单直观,能自动识别类型,是我们日常编程的常用选择。
|
||||
* `scanf/printf`:
|
||||
* **优点**:执行效率更高;拥有强大的**格式控制能力**,能实现精准的输入匹配和带精度的输出。
|
||||
* **缺点**:语法稍显复杂,需要手动匹配占位符和变量类型,并且 `scanf` 必须带 `&`。
|
||||
* **如何选择?** 在需要精确控制输入输出格式(如本讲的例题),就非常推荐使用 `scanf/printf` 。
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
### 参考答案
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. `/ 10`
|
||||
2. `45`
|
||||
3. `cstdio`
|
||||
4. `&`
|
||||
5. `double`
|
||||
6. `User ID: 99`
|
||||
7. `%.1f`
|
||||
8. `7`
|
||||
9. `1`
|
||||
10. `2`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. B
|
||||
2. C
|
||||
3. C
|
||||
4. B (整数除法,结果是2)
|
||||
5. B
|
||||
6. C
|
||||
7. B (`365/10` -> `36`, `36%10` -> `6`)
|
||||
8. B
|
||||
9. B
|
||||
10. B (`8/3` 商2余2)
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. × (反了,`/` 是除法,`%` 是取余)
|
||||
2. √
|
||||
3. × (不安全,用户必须严格输入 `10,20` 才能被读取,不通用)
|
||||
4. √
|
||||
5. × (必须包含 `<cstdio>`)
|
||||
6. √
|
||||
7. × (可以同时输出多个,如 `printf("%d %d", a, b);`)
|
||||
8. √
|
||||
@@ -0,0 +1,74 @@
|
||||
## C++ 整数提取与格式化输入输出 课后习题
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. C++ 中,获取一个整数个位数的“提取器”是 `% 10`,砍掉个位数的“削减器”是 \_\_\_\_\_\__\_\_\_\_。
|
||||
|
||||
2. 表达式 `456 % 10` 的计算结果是 `6`,表达式 `456 / 10` 的计算结果是 \_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
3. 要使用 `printf` 和 `scanf`,必须在代码顶部包含头文件 `#include <________________>`。
|
||||
|
||||
4. 在使用 `scanf` 读取数据时,必须在变量名前面加上符号 \_\_\_\_\_\_\_\_,它叫做取地址符。
|
||||
|
||||
5. 格式说明符 `%d` 用来对应 `int` 类型的整数,`%c` 用来对应 `char` 类型的字符,而 `%lf` 用来对应 \_\_\_\_\_\_\_\_ 类型的变量。
|
||||
|
||||
6. 阅读代码 `printf("User ID: %d", 99);`,它的输出结果是:\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
7. 如果想用 `printf` 输出一个浮点数,并严格保留 `1` 位小数,应该使用的格式说明符是 \_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
8. `int n = 87; printf("%d", n % 10);` 这段代码的输出结果是 \_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
9. `int n; scanf("%d", &n);` 如果用户输入 `123`,那么表达式 `n / 100` 的结果是 \_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
10. 表达式 `(528 / 10) % 10`它的计算结果是 \_\_\_\_\_\_\_\_\_\_\_。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 为了获取整数 `921` 的个位数 `1`,应该使用哪个表达式?
|
||||
A. `921 / 10` B. `921 % 10` C. `921 / 100` D. `921 % 100`
|
||||
|
||||
( ) 2. 下列哪条语句可以**正确**地用 `printf` 输出整数变量 `score` 的值?
|
||||
A. `printf(score);` B. `printf("score");`
|
||||
C. `printf("%d", score);` D. `printf("%d", &score);`
|
||||
|
||||
( ) 3. 下列哪条语句可以**正确**地用 `scanf` 读取一个整数并存入变量 `age` 中?
|
||||
A. `scanf("%d", age);` B. `scanf("%c", &age);`
|
||||
C. `scanf("%d", &age);` D. `scanf("%d", &age)`
|
||||
|
||||
( ) 4. `int a = 5, b = 2;`,`printf("结果是%d", a / b);` 的输出是?
|
||||
A. `结果是2.5` B. `结果是2` C. `结果是%d` D. `结果是3`
|
||||
|
||||
( ) 5. `int n = 73; n = n / 10;` 执行后,`n` 的值变成了?
|
||||
A. `73` B. `7` C. `3` D. `7.3`
|
||||
|
||||
( ) 6. 忘记在 `scanf` 的变量前加 `&` 符号,最可能导致什么后果?
|
||||
A. 程序正常运行 B. 程序会卡住
|
||||
C. 程序在运行时会崩溃或读入错误数据 D. 电脑会蓝屏
|
||||
|
||||
( ) 7. `int num; scanf("%d", &num);` 如果用户输入 `365`,那么 `printf("%d", (num/10)%10);` 会输出什么?
|
||||
A. `3` B. `6` C. `5` D. `36`
|
||||
|
||||
( ) 8. 要输出一个浮点数并保留两位小数,应该用哪个格式说明符?
|
||||
A. `%f` B. `%.2f` C. `%2f` D. `%d.2`
|
||||
|
||||
( ) 9. 拆分一个正整数 `n` 的所有位的通用步骤是?
|
||||
A. 不断地:先用 `/ 10` 削减,再用 `% 10` 提取
|
||||
B. 不断地:先用 `% 10` 提取,再用 `/ 10` 削减
|
||||
C. 只需不断地 `/ 10`
|
||||
D. 只需不断地 `% 10`
|
||||
|
||||
( ) 10. `int x=8, y=3; printf("%d %d", x/y, x%y);` 的输出结果是?
|
||||
A. `2.66 2` B. `2 2` C. `3 2` D. `2 3`
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. 运算符 `/` 是用来求余数的,运算符 `%` 是用来做除法的。
|
||||
( ) 2. `printf` 中的占位符(如 `%d`)和后面的变量,它们的顺序和类型都必须一一对应。
|
||||
( ) 3. `scanf("%d,%d", &a, &b);` 是一个安全的写法,用户输入 `10 20` 就能正确读取。
|
||||
( ) 4. 对于任何正整数 `n`,`n / 10` 都能去掉它的个位数。
|
||||
( ) 5. `printf` 和 `scanf` 都是 C++ 自带的核心功能,不需要包含任何头文件。
|
||||
( ) 6. 整数 `5 % 10` 的结果是 `5`。
|
||||
( ) 7. `printf` 只能输出一个变量,不能同时输出多个。
|
||||
( ) 8. 拆分整数 `520` 时,`520 % 10` 的结果是 `0`。
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+188
@@ -0,0 +1,188 @@
|
||||
### **C++ 顺序结构程序综合实战与解题方法 讲义**
|
||||
|
||||
#### **1. 引言 **
|
||||
|
||||
* **问题引入:我们学会了什么?我们要做什么?**
|
||||
我们已经学会了如何定义变量、运算符和输入输出。已经可以写出一些基本的顺序结构程序了,我们现在要用这些工具,去综合利用解决一个实际问题。而很多同学在面对一个编程题时,会感觉大脑一片空白,不知道第一行代码该怎么写。这很正常!因为目前还缺少一套系统的解题流程。
|
||||
* **价值阐述:为什么要学习解题流程?**
|
||||
一个优秀的程序员,强大的不仅仅是他的代码能力,更是清晰的**逻辑思维和解决问题的能力**。今天要学习的这套流程,就是一个思维框架。它能帮助你:
|
||||
1. **克服做题的恐惧**:面对任何题目,你都有一个可以遵循的“套路”,不会再手足无措。
|
||||
2. **提高效率**:将一个大问题,分解成多个可控的小步骤,避免在错误的方向上浪费时间。
|
||||
3. **提升正确率**:系统性地思考,减少逻辑漏洞。
|
||||
|
||||
---
|
||||
|
||||
#### **2. 顺序程序结构综合练习:如何交换两个变量的值**
|
||||
|
||||
* **问题:如何交换 num1 与 num2 变量里的值**:
|
||||
|
||||
```cpp
|
||||
int num1 = 3, num2 = 4;
|
||||
// ... 在这里写代码 ...
|
||||
cout << num1 << " " << num2 << endl; // 目标:输出 4 3
|
||||
```
|
||||
|
||||
* **错误的尝试**: 很多同学的第一反应是这样的:
|
||||
```cpp
|
||||
num2 = num1; // num2 的值变成了 3
|
||||
num1 = num2; // num1 的值变成了 num2 (也就是3) 的值
|
||||
```
|
||||
**问题出在哪里?** 当你执行 `num2 = num1;` 时,`num2` 原本的值 `4` 就被 `num1` 的值 `3` **覆盖**掉了,永远地丢失了!就像你把一瓶可乐倒进了一瓶装有雪碧的瓶子里,雪碧就没了。
|
||||
|
||||
* **正确的解法:引入第三个“空杯子”**
|
||||
为了不丢失任何一个值,我们需要一个临时的变量(我们称之为 `temp` 或 `num3`)来做中转。
|
||||
|
||||
**例:num1为可乐,num2为雪碧,尝试进行交换:**
|
||||
|
||||
1. `int temp = num1;` (把 num1 的可乐,倒进空杯子 temp 里)
|
||||
2. `num1 = num2;` (把 num2 的雪碧,倒进 num1 杯里, num1 变成了雪碧)
|
||||
3. `num2 = temp;` (把 temp 杯里的可乐,倒进 num2 杯里, num2 变成了可乐)
|
||||
4. **至此,交换成功!**
|
||||
|
||||
* **代码实现**:
|
||||
|
||||
```cpp
|
||||
int num1 = 3, num2 = 4;
|
||||
int temp = num1; // 引入第三个变量
|
||||
num1 = num2; num2 = temp; // 使用空杯子中转一下
|
||||
cout << num1 << " " << num2; // 输出 4 3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### **3. 编程解题的“七步法”**
|
||||
|
||||
现在,让我们以“**小鱼的游泳时间**”这个问题为案例,一步一步地走完我们解题的完整流程。
|
||||
|
||||
##### ==**第一步:读懂题目,明确题目要求“做什么”?**==
|
||||
|
||||
* **原文**:小鱼从 a 时 b 分一直游泳到当天的 c 时 d 分,计算它一共游了多少时间。
|
||||
* **提炼任务**:核心任务是**计算时间差**。我们要用“结束时间”减去“开始时间”。
|
||||
|
||||
##### ==**第二步:理解输入,明确需要输入的原材料是什么?**==
|
||||
|
||||
* **原文**:输入四个整数 a, b, c, d。
|
||||
* **解读**:程序需要从外界接收4个整数。我们必须定义4个 `int` 类型的变量来“接住”这些数据。
|
||||
```cpp
|
||||
int a, b, c, d;
|
||||
cin >> a >> b >> c >> d;
|
||||
```
|
||||
* **重要误区**:绝对不能看到样例输入是 `12 50 19 10` 就在代码里写 `int a = 12;`!样例只是一个例子,我们的程序必须能处理任何合法的输入。**变量的值必须通过 `cin` 来获取!**
|
||||
|
||||
##### ==**第三步:思考解题逻辑,先想出解决问题的思路**==
|
||||
|
||||
在敲代码之前,先把思路理出来。清晰的逻辑思路,远比一开始就埋头敲错误的代码要高效得多。
|
||||
* **实际的问题**:如何计算 `c时d分 - a时b分`?直接减很麻烦,比如 `19时10分 - 12时50分`,分钟不够减,需要向小时借位。
|
||||
* **寻找更简单的方法 -> 统一单位**:
|
||||
所有复杂的多单位计算,都可以通过**转换成统一的最小单位**来简化。这里的最小单位是“分钟”。
|
||||
1. **将所有时间转换为分钟**:
|
||||
* 开始时间(总分钟数)`start = a * 60 + b;`
|
||||
* 结束时间(总分钟数)`end = c * 60 + d;`
|
||||
2. **计算差值**:
|
||||
* 现在游泳的总时长就是开始时间和结束时间的差值 `diff = end - start;`。
|
||||
3. **将结果转换回目标格式**:
|
||||
* 题目要求输出“e小时 f分钟”。我们手上有总分钟数,如何转换回去?
|
||||
* 小时数 `e = diff_minutes / 60;` (利用整数除法自动取整)
|
||||
* 分钟数 `f = diff_minutes % 60;` (利用取余运算得到不够1小时的剩余部分)
|
||||
|
||||
##### ==**第四步:把思路翻译为C++代码”**==
|
||||
|
||||
现在,我们把第三步的逻辑,一行行地用C++语言表达出来。
|
||||
```cpp
|
||||
// 步骤1:统一单位
|
||||
int start = a * 60 + b;
|
||||
int end = c * 60 + d;
|
||||
int diff = ends - start;// 步骤2:计算差值
|
||||
|
||||
// 步骤3:转换格式
|
||||
int e = diff / 60; // 小时
|
||||
int f = diff % 60; // 分钟
|
||||
```
|
||||
|
||||
##### ==**第五步:处理输出,保证格式绝对正确**==
|
||||
|
||||
* **原文**:一行内输出两个整数 e 和 f,用空格间隔。
|
||||
* **解读**:在线评测系统(OJ)要求输出必须和标准答案一模一样,一个空格都不能差。
|
||||
* **代码实现**:
|
||||
```cpp
|
||||
cout << e << " " << f;
|
||||
```
|
||||
|
||||
##### ==**第六步:编译运行,检查语法错误**==
|
||||
|
||||
把所有代码组合起来,在你的编程环境中(如Dev-C++)按下编译运行键(F11)。
|
||||
* 如果出现 `Compile Error (CE)`,仔细阅读编译器给出的错误信息,它会告诉你哪一行出错了,通常是漏了分号、括号不匹配、变量名写错等失误。
|
||||
|
||||
##### ==**第七步:样例测试,验证逻辑的正确性**==
|
||||
|
||||
* **操作**:程序运行后,输入题目给的样例 `12 50 19 10`,然后按回车。
|
||||
|
||||
* **比对**:
|
||||
* 程序输出:`6 20` 并且题目的样例输出:`6 20`
|
||||
* **结果完全一致!** 这说明我们的逻辑在处理这个样例时是正确的。
|
||||
|
||||
* **如果结果不一致怎么办? -> ==使用手动 cout 检查法==**
|
||||
假设你的程序输出了奇怪的结果,比如 `1 -30`。这说明逻辑错了!
|
||||
|
||||
1. **手动在关键位置加入`cout`**:在你代码的关键步骤后,通过`cout`打印出关键的中间变量的值。
|
||||
|
||||
```cpp
|
||||
int start = a * 60 + b;
|
||||
cout << "开始总分钟: " << start << endl; // 实际输出出来看看 start 的值到底是多少,跟我想的是一致的吗
|
||||
int end = c * 60 + d;
|
||||
cout << "结束总分钟: " << end << endl; // 实际输出出来看看 end 的值到底是多少,跟我想的是一致的吗
|
||||
int diff = end - start;
|
||||
cout << "分钟差: " << diff << endl; // 实际输出出来看看最终的结果差的底是多少,跟我自己算出来的是一致的吗
|
||||
```
|
||||
2. **重新运行样例查看输出结果**:输入 `12 50 19 10`。
|
||||
3. **进行核对**:
|
||||
|
||||
* 通过实际在草稿纸上计算:如果输入样例数据`12 50 19 10` 的话,那 `start`就应该是`12*60+50=770`,`end`应该是`19*60+10=1150`,`diff`应该是`380`。
|
||||
* 查看你的程序输出,如果==某个`cout`打印的值和实际算出来不一致==,你就能知道问题出现在什么地方了!**就要仔细进行检查。**
|
||||
|
||||
---
|
||||
|
||||
#### **4. OJ的反馈结果 **
|
||||
|
||||
在我们的题目网站上递交你的代码后,最终它会给你一个结果来告诉我们你的代码是否正确。我们就要学会读懂OJ的反馈的结果。而系统的反馈主要有这几种:
|
||||
|
||||
#### **1. 正确`AC (Accepted)`**
|
||||
|
||||
* **含义**:**正确通过!**恭喜!意味着程序已经通过了所有测试数据。
|
||||
|
||||
#### **2. 编译错误:`CE (Compile Error)`**
|
||||
|
||||
* **含义**:**编译错误**。
|
||||
* **解读**:这是最基础的错误。它意味着你的代码存在**语法问题**,翻译官根本无法读懂你的代码。
|
||||
* **常见的编译错误原因**:
|
||||
1. **漏写分号 (`;`)**:每一句指令的结束标志,就像中文的句号。
|
||||
2. **括号不匹配**:`{}` 和 `()` 总是成双成对出现,少了一半就会出错。
|
||||
3. **使用了中文标点**:代码世界里只认英文标点。中文的 `,;()` 都是非法字符。
|
||||
4. **变量名拼错**:你定义时用的是 `score`,使用时却写成了 `scroe`。
|
||||
5. **变量未定义就使用**:还没准备好盒子(声明变量),就想往里面放东西。
|
||||
* **如何解决**:
|
||||
`CE` 是最容易解决的问题。**在DevC++编程软件中仔细查看错误信息**,它通常会告诉你**哪一行**出错了,并给出一个英文的错误原因。根据提示回到你的代码中修改,直到在本地能够成功编译为止。
|
||||
|
||||
#### **3. 逻辑错误:`WA (Wrong Answer)`**
|
||||
|
||||
* **含义**:**答案错误**。`WA` 意味着你的**程序语法没问题**,也能顺利运行,但在某一组测试数据上,你的程序给出的输出结果和标准答案不一致。这说明,你的**程序设计本身存在逻辑漏洞**。
|
||||
* **如何自查和更正?**:
|
||||
1. **第一步:检查输出格式**
|
||||
* 你的 `cout` 语句里是不是多了不该有的东西?比如 `cout << "答案是:" << sum;`。
|
||||
* 你的输出里是不是少了题目要求的空格或换行?比如要求 `6 20`,你输出了 `620`。
|
||||
2. **第二步:检查你的解题思路**
|
||||
* 如果格式没问题,那一定是逻辑思路出了错。
|
||||
* 拿出草稿纸,重新走一遍你的“七步做题法”中的第三步。你的思路真的能应对所有情况吗?是不是对题目的某个细节理解有偏差?
|
||||
3. **第三步:使用 `cout` 手动检查法**
|
||||
* 在代码的关键计算步骤之后,插入临时的 `cout` 语句,打印出中间变量的值进行检查。
|
||||
* 用比如题目给出的样例来运行你的的程序。观察打印出来的中间值,和你在草稿纸上一步步推算的结果进行比对。一旦发现哪个变量的值与你的预期不符,就找到了程序“不正确的位置!就可以仔细进行检查并修正。
|
||||
|
||||
---
|
||||
|
||||
#### **6. 总结 **
|
||||
|
||||
**请务必牢记着七个编程的基本步骤**:
|
||||
|
||||
==**读懂题目**==(识别核心任务是什么) → ==**理解输入**== (明确输入数据的类型、数量、顺序及格式,并据此在程序中声明相应变量) → ==**思考逻辑**== (设计解决问题的思路) → ==**翻译代码**== (将逻辑思路翻译为具体的C++代码) → ==**处理输出**== (将答案根据题目要求的格式输出) → ==**编译查错**== (检查是否有语法错误) → ==**样例验证**== (使用样例数据对程序进行验证输出与样例输出是否一致)
|
||||
|
||||
养成**先动脑,后动手**的习惯。清晰的逻辑思路,远比一开始就埋头敲错误的代码要高效得多。
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,35 @@
|
||||
### **C++ 顺序结构综合练习 课后习题 - 答案**
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 思考解题逻辑
|
||||
2. 第三个变量,`num1 = num2;`
|
||||
3. 分钟
|
||||
4. `diff / 60` , `diff % 60`
|
||||
5. CE (Compile Error)
|
||||
6. WA (Wrong Answer)
|
||||
7. `cout`
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
1. **D**. 这是错误的交换方法。`num1 = num2;` 后,`num1` 的值变为20。`num2 = num1;` 后,`num2` 的值也保持为20。
|
||||
2. **C**. 样例不通过说明程序逻辑有问题,需要调试修正。
|
||||
3. **B**. `小时数 * 60 + 分钟数` 是正确的换算逻辑。
|
||||
4. **B**. 百分比要换算成小数,且结果可能为小数,应用 `double` 类型存储。
|
||||
5. **C**. AC代表通过了所有测试,是最终的正确结果。
|
||||
6. **C**. WA代表程序能运行但结果不对,这是逻辑或格式上的错误。CE才是语法错误。
|
||||
7. **A**. `125 / 60` 整数除法得 `2`。`125 % 60` 取余数得 `5`。
|
||||
8. **B**. 程序的价值在于处理不确定的、任意的合法输入,所以必须用 `cin`。
|
||||
|
||||
#### **三、 判断题**
|
||||
|
||||
1. √ (这是标准的三变量交换法。)
|
||||
2. √ (讲义的核心思想之一,清晰的逻辑远比盲目试错重要。)
|
||||
3. × (CE是编译错误,即语法错误。WA或TLE等才是逻辑算法错误。)
|
||||
4. × (这种方法无法处理分钟不够减需要向小时借位的情况,统一单位是更简单可靠的方法。)
|
||||
5. × (OJ系统会有更多、更复杂的测试数据,样例通过只是第一步。)
|
||||
6. √ (对于评测系统来说,它只关心最终打印到屏幕上的字符序列是否完全匹配。)
|
||||
7. √ (这是讲义中重点推荐的调试逻辑错误的方法。)
|
||||
8. √ (因为 `* 0.2` 这类运算可能产生小数,用 `int` 会丢失精度。)
|
||||
9. × (这行代码的作用是从键盘读取两个值,分别存入变量 `a` 和 `b`。)
|
||||
10. √ (OJ是“死脑筋”的,格式必须完全一致。)
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
### **C++ 顺序结构设计综合练习 课后习题**
|
||||
|
||||
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
|
||||
|
||||
#### **一、 填空题**
|
||||
|
||||
1. 编程解题的“七步法”强调,在动手将思路翻译成代码之前,更重要的是先\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
2. 为了交换变量 `num1` 和 `num2` 的值,我们需要借助_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。如果第一步是 `temp = num1;`,第三步是 `num2 = temp;`,那么中间的第二步应该是\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
3. 在解决“小鱼的游泳时间”问题时,为了简化计算,我们采用“统一单位”的方法,将“时”和“分”都统一成最小单位\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
4. 在解决“小鱼的游泳时间”问题时,在计算完毕小鱼从开始到结束的游泳时间 `diff` 分钟后,还需要将 `diff` 分钟的形式换算回小时和分钟,那么计算小鱼这天一共游的小时数的表达式为\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_;那么计算小鱼这天一共游的分钟数的表达式为\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_。
|
||||
5. 如果在代码中漏写了分号或使用了中文标点,提交到OJ系统最可能收到的反馈是\_\_\_\_\_\_\_\_\_\_ (填写简称 CE/WA/AC)。
|
||||
6. 如果程序的逻辑有漏洞,例如错把 `a > b` 写成了 `a < b`,导致计算结果错误,提交后最可能收到的反馈是\_\_\_\_\_\_\_\_\_\_\_\_\_\_ (填写简称CE/WA/AC)。
|
||||
7. 当程序运行结果与预期不符时,可以在代码的关键位置加入临时的\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_语句来打印出中间变量的值,这种方法被称为“手动检查法”。
|
||||
|
||||
#### **二、 单项选择题**
|
||||
|
||||
( ) 1. 阅读以下代码,其最终输出是什么?
|
||||
```cpp
|
||||
int num1 = 10, num2 = 20;
|
||||
num1 = num2;
|
||||
num2 = num1;
|
||||
cout << num1 << " " << num2;
|
||||
```
|
||||
A. 10 20   B. 20 10   C. 10 10   D. 20 20
|
||||
|
||||
( ) 2. 根据编程解题“七步法”,当发现样例测试结果与预期不一致时,我们应该进入哪个环节?
|
||||
A. 重新读题,理解要求
|
||||
B. 检查输出格式
|
||||
C. 使用“手动cout检查法”等手段,修复逻辑错误
|
||||
D. 优化代码,提高运行速度
|
||||
|
||||
( ) 3. 对于“小鱼的游泳时间”问题,如果输入的开始时间是 `a` 时 `b` 分,那么将开始时间统一进制转换成分钟数的正确表达式是?
|
||||
A. `a + b * 60`   B. `a * 60 + b`   C. `a * 60 + b * 60`   D. `(a + b) * 60`
|
||||
|
||||
( ) 4. 在“成绩计算”问题中,总成绩 `score = 作业(A)*20% + 小测(B)*30% + 期末(C)*50%`。以下哪段计算代码是正确的?
|
||||
A. `int score = A * 20 + B * 30 + C * 50;`
|
||||
B. `double score = A * 0.2 + B * 0.3 + C * 0.5;`
|
||||
C. `int score = A * 0.2 + B * 0.3 + C * 0.5;`
|
||||
D. `double score = A / 5 + B / 3 + C / 2;`
|
||||
|
||||
( ) 5. 在线评测系统(OJ)返回“Accepted (AC)”,这意味着什么?
|
||||
A. 代码可以成功编译。
|
||||
B. 代码通过了样例测试数据。
|
||||
C. 代码通过了所有的测试数据,程序是完全正确的。
|
||||
D. 代码的格式非常规范。
|
||||
|
||||
( ) 6. 某同学在提交代码后得到了“Wrong Answer (WA)”的反馈,有可能的原因是?
|
||||
A. 代码中漏掉了一个分号`;`。
|
||||
B. 变量名拼写错误。
|
||||
C. 解题的逻辑思路存在问题,或者输出格式与要求不符。
|
||||
D. 使用的变量太多,占用了过多内存。
|
||||
|
||||
( ) 7. 假设变量 `total_minutes` 的值为 `125`,执行以下代码后,输出是什么?
|
||||
```cpp
|
||||
int h = total_minutes / 60;
|
||||
int m = total_minutes % 60;
|
||||
cout << h << " " << m;
|
||||
```
|
||||
A. 2 5   B. 2.08 5   C. 2 15   D. 2 25
|
||||
|
||||
( ) 8. “七步法”中“理解输入”这一步,下列说法正确的是什么?
|
||||
A. 必须在代码中把变量赋值为样例输入的值,如 `int a = 12;`
|
||||
B. 必须使用 `cin` 来从键盘获取不确定的输入值。
|
||||
C. 必须给变量起一个和题目描述中一模一样的名字。
|
||||
D. 必须一次性把所有需要的变量都在程序开头定义好。
|
||||
|
||||
#### **三、 判断题 (对的打“√”,错的打“×”)**
|
||||
|
||||
( ) 1. 交换两个变量 `a` 和 `b` 的值,代码 `int temp = a; a = b; b = temp;` 是正确的。
|
||||
( ) 2. 在编程时,应该先思考好清晰的逻辑,再动手写代码,这样比直接埋头试错更高效。
|
||||
( ) 3. 如果OJ返回 `Compile Error (CE)`,说明是程序的逻辑算法错了。
|
||||
( ) 4. 在“小鱼的游泳时间”问题中,可以直接用结束的分钟减开始的分钟,小时减小时,不需要统一单位。
|
||||
( ) 5. 一个程序在自己的电脑上用了一个样例测试通过了,那么提交到OJ就一定能获得 `AC`。
|
||||
( ) 6. `cout << 6 << " " << 20;` 和 `cout << "6 20";` 对于OJ评测系统来说,输出结果是完全一样的。
|
||||
( ) 7. “手动cout检查法”是定位逻辑错误的有效手段。
|
||||
( ) 8. 在“成绩计算”问题中,因为成绩有小数,所以存储总分的变量最好声明为 `double` 类型。
|
||||
( ) 9. `cin >> a >> b;` 这行代码的作用是,把 `a` 的值赋给 `b`。
|
||||
( ) 10. OJ评测系统对输出格式要求极高,多一个或少一个空格都可能导致 `WA`。
|
||||
BIN
Binary file not shown.
Binary file not shown.
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` 语句块**永远**都会被执行!
|
||||
Loaded 100 of 1789 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user