Files
chouka/old/第08课-函数与抽一次.md
T
2026-05-16 11:09:02 +08:00

137 lines
4.2 KiB
Markdown
Raw 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.
# 第 8 课:函数与「抽一次」(`void`)
**本课目标**:把「随机一次 + 判断稀有度并打印」收成 **一个函数**,需要抽卡时 **调用函数名加括号** 即可,让 `main` 更短、更好读。
**复习**:第 57 课已经会写随机数、`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`