137 lines
4.2 KiB
Markdown
137 lines
4.2 KiB
Markdown
# 第 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 <iostream>
|
||
#include <cstdlib>
|
||
#include <ctime>
|
||
#include <string>
|
||
|
||
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`
|