diff --git a/web/doc/4.1 自定义函数和递归.md b/web/doc/4.1 自定义函数和递归.md index 6ad2e96..c150837 100644 --- a/web/doc/4.1 自定义函数和递归.md +++ b/web/doc/4.1 自定义函数和递归.md @@ -162,7 +162,29 @@ $$ --- -## 四、先看一个最简单的自定义函数 +## 四、函数的意义:同一件事,只写一次 + +先看一个场景。 + +你需要算 3 个同学各自的总分: + +- 小明:语文 92,数学 87,英语 95 +- 小红:语文 78,数学 85,英语 80 +- 小刚:语文 88,数学 90,英语 76 + +如果不用函数,主程序会这样写: + +```cpp +int sum1 = 92 + 87 + 95; // 小明的总分 +int sum2 = 78 + 85 + 80; // 小红的总分 +int sum3 = 88 + 90 + 76; // 小刚的总分 +``` + +如果有 30 个同学,就要写 30 行。 + +而且"加 3 个数"这件事,每次都要重复写一遍。 + +这时可以定义一个函数,把"怎么加"这件事单独写好: ```cpp int total_score(int chinese, int math, int english) @@ -172,43 +194,52 @@ int total_score(int chinese, int math, int english) } ``` -这段代码的意思是: - -1. 接收 3 个整数:语文、数学、英语分数。 -2. 把这 3 个分数加起来,存到 `sum` 里。 -3. 把 `sum` 作为结果交回去。 - -如果在主函数里这样写: +然后在主函数里,每个同学用一行搞定: ```cpp -int chinese = 92; -int math = 87; -int english = 95; -int ans = total_score(chinese, math, english); +int sum1 = total_score(92, 87, 95); // 小明的总分,得到 274 +int sum2 = total_score(78, 85, 80); // 小红的总分,得到 243 +int sum3 = total_score(88, 90, 76); // 小刚的总分,得到 254 ``` -可以把它读成人话: +"怎么算总分"只定义了一次,却被叫了 3 次。 -1. 先准备好 3 个分数:92、87、95。 -2. 调用 `total_score(chinese, math, english)`。 -3. 函数把 3 个分数加起来,得到 274。 -4. 把 274 交回来。 -5. 最后 `ans` 得到 274。 +这就是函数最核心的意义: -### 用流程图走一遍会更清楚 +> 把一件事的做法写一次,想用多少次就叫多少次。 + +### 用流程图看清楚"调用"发生了什么 + +下面这张图展示的是:主函数叫了 `total_score` 两次,每次都跳出去执行函数,结束后再回来继续。 ```mermaid flowchart TD - A([开始]) --> B["主函数:准备 3 个分数\nchinese = 92, math = 87, english = 95"] + A([开始]) --> B["主函数:准备小明的分数\n92, 87, 95"] B --> C["调用 total_score(92, 87, 95)"] - C --> D["函数收到参数\nchinese = 92, math = 87, english = 95"] - D --> E["函数内部计算\nsum = 92 + 87 + 95 = 274"] - E --> F["return 274\n把答案交回主函数"] - F --> G["主函数接住返回值\nans = 274"] - G --> H[/输出 ans 得到 274/] - H --> I([结束]) + + subgraph F["函数 total_score"] + D["收到参数"] --> E["sum = chinese + math + english"] + E --> G["return sum"] + end + + C --> D + G --> H["sum1 = 274,回到主函数"] + + H --> I["准备小红的分数\n78, 85, 80"] + I --> J["调用 total_score(78, 85, 80)"] + J --> D + G --> K["sum2 = 243,回到主函数"] + + K --> L[/输出 sum1, sum2/] + L --> M([结束]) ``` +注意流程图里的关键点: + +- 每次调用,都会"跳进"函数那个框里执行。 +- 函数执行完以后,再"跳回"主函数继续往下走。 +- 函数本身的代码只写了一份,但被用了两次。 + --- ## 五、值传递到底是什么意思?