Initial commit: C++ courseware

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

No files matched your search

@@ -0,0 +1,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++代码) → ==**处理输出**== (将答案根据题目要求的格式输出) → ==**编译查错**== (检查是否有语法错误) → ==**样例验证**== (使用样例数据对程序进行验证输出与样例输出是否一致)
养成**先动脑,后动手**的习惯。清晰的逻辑思路,远比一开始就埋头敲错误的代码要高效得多。
@@ -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是“死脑筋”的,格式必须完全一致。)
@@ -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. 当程序运行结果与预期不符时,可以在代码的关键位置加入临时的\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_语句来打印出中间变量的值,这种方法被称为“手动检查法”。
#### **二、 单项选择题**
( &nbsp; ) 1. 阅读以下代码,其最终输出是什么?
```cpp
int num1 = 10, num2 = 20;
num1 = num2;
num2 = num1;
cout << num1 << " " << num2;
```
​ A. 10 20 &emsp; B. 20 10 &emsp; C. 10 10 &emsp; D. 20 20
( &nbsp; ) 2. 根据编程解题“七步法”,当发现样例测试结果与预期不一致时,我们应该进入哪个环节?
A. 重新读题,理解要求
B. 检查输出格式
C. 使用“手动cout检查法”等手段,修复逻辑错误
D. 优化代码,提高运行速度
( &nbsp; ) 3. 对于“小鱼的游泳时间”问题,如果输入的开始时间是 `a` 时 `b` 分,那么将开始时间统一进制转换成分钟数的正确表达式是?
A. `a + b * 60` &emsp; B. `a * 60 + b` &emsp; C. `a * 60 + b * 60` &emsp; D. `(a + b) * 60`
( &nbsp; ) 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;`
( &nbsp; ) 5. 在线评测系统(OJ)返回“Accepted (AC)”,这意味着什么?
A. 代码可以成功编译。
B. 代码通过了样例测试数据。
C. 代码通过了所有的测试数据,程序是完全正确的。
D. 代码的格式非常规范。
( &nbsp; ) 6. 某同学在提交代码后得到了“Wrong Answer (WA)”的反馈,有可能的原因是?
A. 代码中漏掉了一个分号`;`。
B. 变量名拼写错误。
C. 解题的逻辑思路存在问题,或者输出格式与要求不符。
D. 使用的变量太多,占用了过多内存。
( &nbsp; ) 7. 假设变量 `total_minutes` 的值为 `125`,执行以下代码后,输出是什么?
```cpp
int h = total_minutes / 60;
int m = total_minutes % 60;
cout << h << " " << m;
```
​ A. 2 5 &emsp; B. 2.08 5 &emsp; C. 2 15 &emsp; D. 2 25
( &nbsp; ) 8. “七步法”中“理解输入”这一步,下列说法正确的是什么?
A. 必须在代码中把变量赋值为样例输入的值,如 `int a = 12;`
B. 必须使用 `cin` 来从键盘获取不确定的输入值。
C. 必须给变量起一个和题目描述中一模一样的名字。
D. 必须一次性把所有需要的变量都在程序开头定义好。
#### **三、 判断题 (对的打“√”,错的打“×”)**
( &nbsp; ) 1. 交换两个变量 `a` 和 `b` 的值,代码 `int temp = a; a = b; b = temp;` 是正确的。
( &nbsp; ) 2. 在编程时,应该先思考好清晰的逻辑,再动手写代码,这样比直接埋头试错更高效。
( &nbsp; ) 3. 如果OJ返回 `Compile Error (CE)`,说明是程序的逻辑算法错了。
( &nbsp; ) 4. 在“小鱼的游泳时间”问题中,可以直接用结束的分钟减开始的分钟,小时减小时,不需要统一单位。
( &nbsp; ) 5. 一个程序在自己的电脑上用了一个样例测试通过了,那么提交到OJ就一定能获得 `AC`。
( &nbsp; ) 6. `cout << 6 << " " << 20;` 和 `cout << "6 20";` 对于OJ评测系统来说,输出结果是完全一样的。
( &nbsp; ) 7. “手动cout检查法”是定位逻辑错误的有效手段。
( &nbsp; ) 8. 在“成绩计算”问题中,因为成绩有小数,所以存储总分的变量最好声明为 `double` 类型。
( &nbsp; ) 9. `cin >> a >> b;` 这行代码的作用是,把 `a` 的值赋给 `b`。
( &nbsp; ) 10. OJ评测系统对输出格式要求极高,多一个或少一个空格都可能导致 `WA`。