# 第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 是不是素数: - 试 2:17 ÷ 2 = 8 余 1,不行 - 试 3:17 ÷ 3 = 5 余 2,不行 - 试 4:17 ÷ 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 #include 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.