Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
@@ -0,0 +1,393 @@
|
||||
# 第一章 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
|
||||
double y = pow(2, 5); // 计算 2 的 5 次方,结果为 32
|
||||
```
|
||||
|
||||
### 例题
|
||||
|
||||
**题目:** 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`。圆周率在程序运行期间不应改变,因此定义为常量。
|
||||
|
||||
**变量覆盖示例:猴子吃桃倒推。**
|
||||
|
||||
```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>
|
||||
|
||||
### 三、程序设计
|
||||
|
||||
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.
@@ -0,0 +1 @@
|
||||
while 循环
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
while 循环的余下部分,把while循环的一尺之锤的例题讲解并让学生课堂完成,讲解ppt while循环的余下部分
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
while 循环的余下部分,讲解循环n次,讲解ppt while循环的累加与遍历和筛选模式
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
复习讲解循环n次,while循环的累加,讲解遍历和筛选模式
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
OJ 题目 P0058 翻倍达标、P0059 阶梯存钱、P0060 筛选编号
|
||||
|
||||
作业: B0055 小玉在游泳
|
||||
Reference in new issue
Block a user