# 第 8 课:函数与「抽一次」(`void`) **本课目标**:把「随机一次 + 判断稀有度并打印」收成 **一个函数**,需要抽卡时 **调用函数名加括号** 即可,让 `main` 更短、更好读。 **复习**:第 5~7 课已经会写随机数、`if`、打印结果;本课不学新概念语法难度,学 **怎么把代码打包复用**。 --- ## 1. 这一课要搞懂什么 - **函数**:一块有名字的代码,写一次,到处可以 **调用**。 - **`void`**:表示这个函数 **不返回数值给调用者**(先记住:打印抽卡结果就够了,不必 `return` 一个数)。 - **函数名**:用小写字母和下划线也可以,本课用 **`draw_once`**(抽一次)。 - **调用**:在 `main` 里写 **`draw_once();`** 就像按一下「抽一次」按钮。 ### 顺序要注意 在 C++ 里,`main` 里如果出现 **`draw_once()`**,编译器要先 **认识** `draw_once` 是什么。有两种常见写法(二选一即可): 1. **把整个函数写在 `main` 上面**(本课推荐,最简单)。 2. 或者在 `main` **上面** 写一行 **`void draw_once();`**(声明),再把 `{ ... }` 写在 `main` **下面**(以后再熟练)。 --- ## 2. 示例:`draw_once` + 在 `main` 里抽两次 保存为 `lession8.cpp`: ```cpp #include #include #include #include void draw_once() { int r = std::rand() % 100; if (r < 70) { std::cout << "普通卡\n"; } else if (r < 95) { std::cout << "稀有卡\n"; } else { std::cout << "超稀有卡\n"; } } int main() { std::srand(std::time(nullptr)); draw_once(); draw_once(); return 0; } ``` 运行应看到 **两行** 抽卡结果(各随机)。 --- ## 3. 为什么要写成函数? | 好处 | 说明 | |------|------| | **少重复** | 不用把一大段 `rand` + `if` 复制很多遍 | | **好改** | 改概率只改 `draw_once` 里面一处 | | **接菜单** | 第 9 课菜单里「选抽卡」只要调用 `draw_once()` | --- ## 4. 和第 6 课的 `for` 怎么配合? 多抽不必手写多个 `draw_once();`,可以: ```cpp int n = 0; std::cout << "抽几次?"; std::cin >> n; for (int i = 1; i <= n; i++) { std::cout << "第" << i << "抽:"; draw_once(); } ``` (把 `srand` 留在 `main` 开头**一次**,不要放进 `draw_once` 里反复执行。) --- ## 5. 能不能把卡名(数组)也放进函数? 可以。当函数里要用 `cards` 时,要么: - 把数组写在 **`main` 外面**(全局,下一小阶段再细讲),要么 - 以后学 **参数** 把数组传进函数。 本课 **最低目标**:先掌握 **`void draw_once()` 无参数版本**;卡名进阶可当练习。 --- ## 6. 怎么编译和运行 ```bash clang++ -std=c++17 -o lession8 lession8.cpp ./lession8 ``` --- ## 7. 本课课堂小练习 1. 把函数名改成你喜欢的英文(例如 `chou_yi_ci`),记得 **`void` 那一行** 和 **`main` 里的调用** 一起改。 2. 用 **`for`** + **`cin >> n`**,循环里调用 **`draw_once()`**,实现和第 6 课类似的「连抽」,但 **`main` 里尽量不要重复写判稀有的大段 `if`**。 --- ## 8. 本课课后作业(选做) - 在 `draw_once` 里增加打印本次 **`r`**(点数),方便对照区间。 - 问家长:**「调用函数」和「复制粘贴同一段代码」相比,哪个更像现实中「按按钮」?** --- ## 9. 常见小问题 - **`draw_once` 写在 `main` 下面且没有声明**:可能报错「找不到这个名字」,把它整块移到 `main` **上面**,或加前置声明。 - **在 `draw_once` 里写 `srand`**:每抽一次都重置种子的话,随机性可能变差;种子只在程序开始时设一次更好。 - **函数末尾忘了 `}`**:大括号要配对,和 `main` 一样。 --- ## 10. 下一课预告 第 9 课做 **菜单**:用 **`while (true)`** 反复显示「抽卡 / 说明 / 退出」,选抽卡就调用 **`draw_once()`**,选退出用 **`break`** 结束循环。 --- *学完请家长在 `学习进度与状态.md` 里更新第 8 课的状态与作业完成情况。* **下一课文档**:`第09课-菜单与循环.md`