第7课:函数——C++的编程模块

学习创建你自己的“专业工人”,把大任务分解成小模块,让代码更整洁、更强大!

环节一:函数:程序的“专业工人”

函数就像一个个身怀绝技的工人,每个工人只负责一件事,并把它做到最好。

食谱卡片:求立方

函数就像一张食谱。点击卡片,看看输入“原料”后能做出什么“菜肴”!

食谱 (调用)

cube(3.0);

菜肴 (返回值)

27.0

一个函数必须有三要素:原型(说明书)、定义(制作过程)和调用(使用它)。

代码示例

#include <iostream> using namespace std; // 1. 函数原型 (告诉编译器有这样一个工具) double cube(double x); int main() { double num = 3.0; // 3. 函数调用 (在main函数里使用这个工具) double result = cube(num); cout << num << " 的立方是 " << result << endl; return 0; } // 2. 函数定义 (说明工具具体怎么工作) double cube(double x) { // return 关键字把结果“送回”给调用它的地方 return x * x * x; }

环节二:参数传递:复印件 vs. 图书馆钥匙

给函数传递信息有两种主要方式:一种是给复印件,一种是给原件的钥匙。

按值传递:复印机

当你传递普通变量(如 `int`, `double`)时,函数得到的是一个**复印件**。函数对复印件的修改,**不会**影响原件。

main()的原件

apples = 5

函数拿到的复印件

数组传递:图书馆钥匙

当你传递数组时,函数得到的是数组的**地址**(就像一把图书馆的钥匙)。函数可以直接修改**原始数组**。

main()的原始数组

scores[0] = 90

函数拿到的钥匙

🔑

环节三:函数与数组的协作

处理数组是函数的常见任务。记住,传递数组时必须同时告诉函数数组有多大。

代码示例:保护数组

#include <iostream> const int MAX_SIZE = 5; using namespace std; // int arr[] 和 int* arr 是一样的 // n 告诉函数数组的大小 // const 关键字像一个“保护锁”,防止函数修改数组 void show_array(const int arr[], int n); int main() { int scores[MAX_SIZE] = {88, 92, 75, 100, 95}; show_array(scores, MAX_SIZE); return 0; } void show_array(const int arr[], int n) { cout << "成绩是: "; for (int i = 0; i < n; i++) { cout << arr[i] << " "; // arr[i] = 0; // 如果取消这行注释,会报错! // 因为arr被const保护了。 } cout << endl; }

函数处理其他类型

处理C-风格字符串

它本质上也是 `char` 数组,同样传递地址。但它很聪明,用末尾的 `\0` 来标记结束,所以**不需要**额外传递长度。

`int count_chars(const char* str);`

处理string类和结构体

它们更像普通变量,默认按值传递(传递复印件)。如果它们很大,为了效率,我们也可以传递它们的地址(指针)。

`void show_struct(const Student& stu);`

环节四:高级主题:递归与函数指针

来见识一下函数更神奇的两种用法!

递归:俄罗斯套娃

递归就是函数调用自己。就像一个不断打开自己的套娃,直到遇见最小的那个(停止条件)。

函数指针:灵活的调度员

函数指针是一个特殊的变量,它存储的不是数字或文字,而是**一个函数的地址**。

这允许我们把一个函数作为参数传递给另一个函数,让程序变得非常灵活。

// pf 是一个指向函数的指针 // 这个函数接收一个 double, 返回一个 double double (*pf)(double); // 让 pf 指向 cube 函数 pf = cube; // 通过指针调用函数 double result = (*pf)(5.0); // result is 125.0

魔法师的挑战

是时候检验你的学习成果了!尝试完成下面的任务吧。

练习 1:调和平均数

任务:

编写一个函数 `harmonic_mean(double x, double y)`,计算两个数的调和平均数并返回结果。公式为:2.0 * x * y / (x + y)。

点击查看参考答案
#include <iostream> using namespace std; double harmonic_mean(double x, double y); int main() { double num1, num2; cout << "请输入两个数字 (输入0结束):" << endl; while (cin >> num1 && num1 != 0 && cin >> num2 && num2 != 0) { double mean = harmonic_mean(num1, num2); cout << "调和平均数是: " << mean << endl; cout << "请再输入两个数字 (输入0结束):" << endl; } return 0; } double harmonic_mean(double x, double y) { return 2.0 * x * y / (x + y); }
练习 2:高尔夫球成绩处理

任务:

编写三个函数:`fill_array`(读取成绩),`show_array`(显示成绩,不得修改),和 `average`(计算平均分)。在main中调用它们处理最多10个分数。

点击查看参考答案
#include <iostream> using namespace std; const int Max = 10; int fill_array(double arr[], int limit); void show_array(const double arr[], int n); double average(const double arr[], int n); int main() { double scores[Max]; int actual_size = fill_array(scores, Max); if (actual_size > 0) { show_array(scores, actual_size); cout << "平均成绩是: " << average(scores, actual_size) << endl; } return 0; } int fill_array(double arr[], int limit) { /* ...内容见大纲... */ return 0; } void show_array(const double arr[], int n) { /* ...内容见大纲... */ } double average(const double arr[], int n) { /* ...内容见大纲... */ return 0.0; }
练习 3:盒子结构体

任务:

定义`struct box`。编写函数 `show_box`(按值传递)和 `calculate_volume`(按地址传递,计算并设置体积)。

点击查看参考答案
#include <iostream> using namespace std; struct box { double length, width, height, volume; }; void show_box(const box b); void calculate_volume(box * pb); int main() { box my_box = {10.0, 5.0, 2.0, 0.0}; show_box(my_box); calculate_volume(&my_box); show_box(my_box); return 0; } void show_box(const box b) { cout << "L: " << b.length << ", W: " << b.width << ", H: " << b.height << ", V: " << b.volume << endl; } void calculate_volume(box * pb) { pb->volume = pb->length * pb->width * pb->height; }