Files
project1/第05课-自定义函数/教案-教师版.md

172 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第3课自定义函数教学拓展
> 等级说明:自定义函数属于 GESP 四级知识。本课程保留这一课,是为了训练代码分解和复用能力,不作为一级、二级考试必考内容。
## 教学目标
- 掌握函数的定义、调用与声明
- 理解形参与实参、返回值、void函数
- 理解函数重载(同名不同参)
- 理解局部变量与全局变量的作用域
## 核心考点:函数的参数、返回值与调用过程
### 考什么
常见题型包括补全函数定义、判断形参与实参、根据调用过程求输出,以及把一段重复逻辑封装成函数。重点是看懂数据怎样进入函数、函数怎样处理、结果怎样返回主程序。
### 必须理解
定义函数时括号里的变量叫形参,是函数内部接收数据的“临时名字”;调用函数时传入的值叫实参。普通值传递会把实参复制给形参,函数内部修改形参通常不会改变外面的变量。执行到 `return` 时,函数立即结束并把结果交回调用位置;`void` 函数不返回结果。局部变量只在所属的大括号内有效,不同函数中的同名局部变量互不影响。
### 核心写法
```cpp
int maxValue(int a, int b) { // a、b 是形参
if (a > b) return a;
return b;
}
int answer = maxValue(x, y); // x、y 是实参
```
调用时先计算实参,再进入函数执行;遇到 `return` 后回到原调用位置,把返回值赋给 `answer`
### 常见错误
- 声明的返回类型是 `int`,却忘记写 `return`
- 把函数定义写进 `main` 内部C++ 不允许在函数内部再定义普通函数。
- 以为修改普通形参就会修改实参,混淆“值的复制”和“原变量”。
- 在变量作用域之外使用局部变量。
### 判断是否掌握
能画出“实参传入→形参接收→函数执行→return 返回→主程序继续”的过程,并能独立编写一个有参数、有返回值的判断或计算函数。
---
## 题目一:判断素数
### 核心代码(一句话)
> 判断素数的核心:**从 2 试到 √n只要有一个能整除就不是素数。**
### 自然语言思路
素数就是"除了1和自己不能被任何数整除"的数。
比如判断 17 是不是素数:
- 试 217 ÷ 2 = 8 余 1不行
- 试 317 ÷ 3 = 5 余 2不行
- 试 417 ÷ 4 = 4 余 1不行
- 试到 √17 ≈ 4.1,所以只需试到 4
- 全都不行 → 17 是素数!
为什么只试到 **√n**?因为如果 n 有一个大于 √n 的因数,那一定会有一个小于 √n 的因数跟它配对。比如 36 = 6 × 6一个因数大于 6另一个必然小于 6。所以试到 √n 就够了。
**为什么要写成函数?** 判断素数的代码以后经常用到,封装成 `isPrime(n)`,以后需要时一行调用,不用重复写。
### 伪代码
```
函数 isPrime(n):
如果 n < 2: 返回 false // 1 不是素数
对于 i 从 2 到 sqrt(n):
如果 n % i == 0: // 能被整除
返回 false // 不是素数,直接返回
返回 true // 全都试过了,是素数
主程序:
输入 m
如果 isPrime(m): 输出 "YES"
否则: 输出 "NO"
```
### 真实代码
```cpp
#include <iostream>
#include <cmath>
using namespace std;
// 函数定义:判断素数
bool isPrime(int n) {
if (n < 2) return false; // 1 和负数不是素数
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) return false; // 找到因数,不是素数
}
return true; // 全部试完,是素数
}
int main() {
int m;
cin >> m;
if (isPrime(m)) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
return 0;
}
```
### 注意点
1. **1 不是素数**:必须在函数开头处理 `n < 2` 的情况,这是 GESP 高频易错点。
2. **为什么 `i <= sqrt(n)` 而不是 `i < n`**:前者效率高很多。判断 100 是否是素数,试到 10 就够了,不用试到 99。
3. **`sqrt` 返回 double**`i <= sqrt(n)` 是 int 和 double 比较C++ 会自动转换,没问题。但如果担心精度,可以写成 `i * i <= n`
4. **函数名要有意义**`isPrime` 一看就知道是"判断素数",比 `f``check` 好得多。
5. **局部变量 i**i 只在 isPrime 函数里有效main 里访问不到它 —— 这就是**局部变量**的作用域。
---
## 题目二:(待橙子补充)
> 建议覆盖函数重载、void函数等
---
### 核心代码(一句话)
>
### 自然语言思路
### 伪代码
### 真实代码
```cpp
```
### 注意点
---
## 题目三:(待橙子补充)
> 建议覆盖:局部变量与全局变量对比
---
### 核心代码(一句话)
>
### 自然语言思路
### 伪代码
### 真实代码
```cpp
```
### 注意点
---
## 本课打油诗
> 函数写好存身旁,起名调用响当当。
> 参数传进返结果,少写重复心不慌。
---
## 课后作业
(待补充)
1.
2.