LESSON 2.12 · 公开免费
2.12 函数入门——把程序拆成小工具
课程正文由飞书云文档同步,并使用慧博算法实验室的教学样式呈现。
MISSION · 本课任务
当程序越来越长时,如果把所有代码都写在 main() 中,程序会变得难以阅读,也不方便重复使用。
函数可以把一段具有特定功能的代码包装成一个小工具。
学完本课,你将能够:
✅ 理解函数的作用
✅ 定义并调用自己的函数
✅ 理解参数和返回值
✅ 认识 int、double、bool 和 void 函数
✅ 理解函数声明与函数定义
✅ 使用 min、max、abs、sqrt 和 pow
✅ 使用 sort 对数组和 vector 排序
✅ 使用函数解决具体问题
1 函数是什么
想象我们有一台果汁机:
放入水果 → 启动机器 → 得到果汁函数的工作过程也很相似:
传入数据 → 执行代码 → 返回结果例如,我们想计算两个整数的和,可以创建一个函数:
int add(int a, int b) {
int result = a + b;
return result;
}这个函数叫作 add。
它的作用是:
接收两个整数,计算它们的和,并把结果返回。
完整程序:
#include <iostream>
using namespace std;
int add(int a, int b) {
int result = a + b;
return result;
}
int main() {
int answer = add(10, 20);
cout << answer;
return 0;
}输出:
30其中:
add(10, 20)表示调用 add 函数。
程序会进入函数:
int add(int a, int b)把:
10交给a
20交给b然后计算:
a + b最后通过:
return result;把结果返回给 main()。
2 函数的基本结构
一个普通函数通常包含四个部分:
返回值类型 函数名称(参数列表) {
函数中的代码
return 返回结果;
}例如:
int add(int a, int b) {
return a + b;
}返回值类型
int表示这个函数执行结束后,会返回一个整数。
函数名称
add函数名称用于调用函数。
函数名称应该尽量体现它的作用,例如:
add
getMax
isEven
calculateArea
printMessage参数列表
int a, int b参数是函数接收的数据。
这个函数需要接收两个整数,所以有两个参数。
函数体
{
return a + b;
}大括号中的内容是调用函数时真正执行的代码。
返回结果
return a + b;return 会把结果交回调用函数的位置,同时结束当前函数。
3 参数和返回值
什么是参数
参数是调用函数时交给函数的数据。
定义函数:
int add(int a, int b) {
return a + b;
}调用函数:
int result = add(8, 5);调用时:
8传给参数a
5传给参数b所以函数计算:
8 + 5 = 13最终:
result中保存13。
形参与实参
函数定义中的参数:
int add(int a, int b)这里的 a 和 b 叫作形式参数,简称形参。
调用函数时传入的数据:
add(8, 5)这里的 8 和 5 叫作实际参数,简称实参。
可以简单理解为:
形参是函数准备好的接收位置,实参是调用时真正传进去的数据。
参数的数量要对应
函数需要两个参数:
int add(int a, int b)正确调用:
add(10, 20);错误调用:
add(10);
add(10, 20, 30);参数类型要合适
函数要求两个整数:
int add(int a, int b)调用时通常也应该传入整数:
add(3, 7);也可以传入整数变量:
int x = 3;
int y = 7;
cout << add(x, y);返回值可以直接使用
cout << add(10, 20);也可以参与运算:
int result = add(10, 20) * 2;还可以作为另一个函数的参数:
cout << max(add(3, 5), 6);先计算:
add(3, 5)得到8,再计算:
max(8, 6)最后得到8。
4 不同类型的函数
函数前面的类型表示函数返回什么样的数据。
返回整数的函数
int square(int x) {
return x * x;
}调用:
cout << square(6);输出:
36返回小数的函数
计算圆的面积:
double circleArea(double radius) {
return 3.1415926 * radius * radius;
}调用:
double area = circleArea(5.0);
cout << area;函数返回小数,所以返回值类型是:
double返回真假的函数
判断一个整数是不是偶数:
bool isEven(int x) {
return x % 2 == 0;
}调用:
if (isEven(8)) {
cout << "8是偶数";
}因为:
8 % 2 == 0结果为真,所以函数返回 true。
判断奇数:
bool isOdd(int x) {
return x % 2 != 0;
}判断是否及格:
bool isPassed(int score) {
return score >= 60;
}bool 函数经常用来回答:
是不是?
有没有?
能不能?因此,函数名称经常以 is、has、can 开头。
不返回结果的函数
有些函数只负责完成一件事,不需要返回数据。
例如,输出一条分隔线:
void printLine() {
cout << "--------------------" << endl;
}调用:
printLine();void 表示:
这个函数不返回结果。
再例如:
void sayHello(string name) {
cout << "你好," << name << "!" << endl;
}调用:
sayHello("Alice");
sayHello("Tom");输出:
你好,Alice!
你好,Tom!常见函数类型
返回整数:
int返回小数:
double返回字符:
char返回字符串:
string返回真假:
bool不返回结果:
void5 函数的位置、声明与变量范围
函数通常写在main前面
#include <iostream>
using namespace std;
int add(int a, int b) {
return a + b;
}
int main() {
cout << add(3, 5);
return 0;
}编译器按照从上到下的顺序阅读程序。
当它在 main() 中看到:
add(3, 5)它已经在前面见过 add 函数,因此知道如何调用。
函数也可以写在main后面
如果想把函数定义写在 main() 后面,需要先进行函数声明:
#include <iostream>
using namespace std;
int add(int a, int b);
int main() {
cout << add(3, 5);
return 0;
}
int add(int a, int b) {
return a + b;
}这一行:
int add(int a, int b);叫作函数声明。
它提前告诉编译器:
后面有一个名叫add的函数
它接收两个整数
它会返回一个整数注意,函数声明的末尾有分号:
int add(int a, int b);函数定义的末尾没有分号:
int add(int a, int b) {
return a + b;
}函数中的局部变量
观察:
int add(int a, int b) {
int result = a + b;
return result;
}其中:
a
b
result都只属于 add 函数。
在 main() 中不能直接使用:
cout << result;这种只在某个函数内部有效的变量叫作局部变量。
不同函数中可以出现同名变量:
int add(int a, int b) {
int result = a + b;
return result;
}
int multiply(int a, int b) {
int result = a * b;
return result;
}两个 result 分别属于不同的函数,不会互相影响。
6 C++常用工具函数
C++已经为我们准备了许多常用函数,不需要每次都自己编写。
min和max
使用头文件:
#include <algorithm>求两个数的较小值:
cout << min(8, 5);输出:
5求两个数的较大值:
cout << max(8, 5);输出:
8也可以使用变量:
int a = 20;
int b = 35;
int smaller = min(a, b);
int larger = max(a, b);应用:限制游戏角色的生命值不能超过100。
int health = 120;
health = min(health, 100);结果:
health = 100应用:保证分数不能低于0。
int score = -5;
score = max(score, 0);结果:
score = 0abs绝对值
绝对值表示一个数到0的距离。
cout << abs(-8);输出:
8cout << abs(5);输出:
5应用:计算两个数之间相差多少。
int a = 15;
int b = 9;
cout << abs(a - b);输出:
6因为无论:
a - b是正数还是负数,绝对值都会得到非负结果。
sqrt平方根
使用头文件:
#include <cmath>计算平方根:
cout << sqrt(81);输出:
9再例如:
double result = sqrt(2);
cout << result;sqrt(2) 的结果是一个小数。
注意:
sqrt(x) 中的 x 应该大于或等于0。
pow乘方
计算2的10次方:
cout << pow(2, 10);输出:
1024其中:
pow(a, b)表示计算:
a的b次方例如:
pow(3, 2)表示:
3² = 9计算平方时,也可以直接写:
x * x对于简单的整数平方, 通常更加直观。
sort排序
使用头文件:
#include <algorithm>sort 可以把数据按照从小到大的顺序排列。
对普通数组排序:
int a[5] = {8, 3, 10, 2, 6};
sort(a, a + 5);排序后:
2 3 6 8 10输出:
for (int i = 0; i < 5; i++) {
cout << a[i] << " ";
}其中:
sort(a, a + 5);表示排序的范围是:
从a[0]开始,到a[5]之前结束也就是排序:
a[0]~a[4]如果实际输入了 n 个元素:
sort(a, a + n);对vector排序
vector<int> a = {8, 3, 10, 2, 6};
sort(a.begin(), a.end());排序后:
2 3 6 8 10其中:
a.begin()表示第一个元素的位置。
a.end()表示最后一个元素之后的位置。
从大到小排序
sort(a.begin(), a.end(), greater<int>());需要包含:
#include <functional>排序结果:
10 8 6 3 27 使用函数解决具体问题
问题一:计算两点之间的距离
平面上有两个点:
A(x₁, y₁)
B(x₂, y₂)两点之间的距离公式是:
√((x₁-x₂)²+(y₁-y₂)²)可以把这个计算过程包装成函数:
double pointDistance(int x1, int y1, int x2, int y2) {
int dx = x1 - x2;
int dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}完整程序:
#include <iostream>
#include <cmath>
using namespace std;
double pointDistance(int x1, int y1, int x2, int y2) {
int dx = x1 - x2;
int dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}
int main() {
int x1, y1;
int x2, y2;
cin >> x1 >> y1;
cin >> x2 >> y2;
cout << pointDistance(x1, y1, x2, y2);
return 0;
}输入:
0 0
3 4输出:
5使用函数后,main() 中不需要关心距离公式的具体细节。
只需要调用:
pointDistance(x1, y1, x2, y2)问题二:判断一个数是否为偶数
创建判断函数:
bool isEven(int x) {
return x % 2 == 0;
}完整程序:
#include <iostream>
using namespace std;
bool isEven(int x) {
return x % 2 == 0;
}
int main() {
int n;
cin >> n;
if (isEven(n)) {
cout << "偶数";
} else {
cout << "奇数";
}
return 0;
}这个程序把任务分成了两部分:
isEven函数:负责判断
main函数:负责输入和输出问题三:数组排序后寻找最值
输入 n 个整数,将它们从小到大排列,然后输出最小值、最大值和排序后的数组。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printVector(vector<int> a) {
for (int i = 0; i < a.size(); i++) {
cout << a[i] << " ";
}
cout << endl;
}
int main() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a.begin(), a.end());
cout << "最小值:" << a.front() << endl;
cout << "最大值:" << a.back() << endl;
cout << "排序结果:";
printVector(a);
return 0;
}输入:
5
8 3 10 2 6输出:
最小值:2
最大值:10
排序结果:2 3 6 8 10这里:
sort(a.begin(), a.end());负责排序。
printVector(a);负责输出整个 vector。
不同的函数分别完成不同的任务,程序结构会更加清晰。
问题四:找到最接近目标的数字
输入若干整数和一个目标值,找到与目标值相差最小的数字。
例如:
数组:3 12 18 25 30
目标:20每个数字与20的距离:
|3-20| = 17
|12-20| = 8
|18-20| = 2
|25-20| = 5
|30-20| = 10所以最接近20的是18。
参考程序:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
int n, target;
cin >> n >> target;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int answer = a[0];
int minDistance = abs(a[0] - target);
for (int i = 1; i < n; i++) {
int currentDistance = abs(a[i] - target);
if (currentDistance < minDistance) {
minDistance = currentDistance;
answer = a[i];
}
}
cout << answer;
return 0;
}这个问题中,abs() 帮助我们计算两个数字之间的距离。
8 常见错误与本课小结
错误一:函数声明和调用不一致
定义:
int add(int a, int b)错误调用:
add(10);函数需要两个参数,调用时也要传入两个参数。
错误二:返回值类型与结果不合适
int average(int a, int b) {
return (a + b) / 2.0;
}函数返回的是小数,但类型写成了 int,小数部分会丢失。
应该写成:
double average(int a, int b) {
return (a + b) / 2.0;
}错误三:有返回值的函数忘记return
错误:
int square(int x) {
int result = x * x;
}正确:
int square(int x) {
int result = x * x;
return result;
}错误四:把函数调用写成函数名称
错误:
cout << square;正确:
cout << square(5);调用函数时需要小括号。
错误五:sort的结束位置写错
错误:
sort(a, a + n - 1);这不会包含最后一个元素。
正确:
sort(a, a + n);sort 的结束位置指向最后一个元素的后面。
本课工具箱
定义整数函数:
int add(int a, int b) {
return a + b;
}定义真假函数:
bool isEven(int x) {
return x % 2 == 0;
}定义无返回值函数:
void printLine() {
cout << "--------" << endl;
}调用函数:
int result = add(3, 5);常用工具函数:
min(a, b)
max(a, b)
abs(x)
sqrt(x)
pow(a, b)普通数组排序:
sort(a, a + n);vector 排序:
sort(a.begin(), a.end());最重要的认识:
函数是一个可以被反复调用的小工具。 参数是交给函数的数据,返回值是函数计算出的结果。 把大问题拆成多个小函数,程序会更清晰、更容易修改。
CHECKPOINT · 课后检查
- 函数有什么作用?
- 函数的返回值类型写在什么位置?
- 什么是函数的参数?
- 形参和实参有什么区别?
return有什么作用?int函数和double函数有什么区别?bool函数适合解决什么问题?void表示什么?- 函数定义写在
main()后面时,为什么需要函数声明? - 什么是局部变量?
min和max分别有什么作用?abs适合解决什么问题?sqrt(81)的结果是多少?pow(2, 10)表示什么?- 如何对普通数组的前
n个元素排序? - 如何对整个
vector排序? - 为什么使用函数后,程序更容易阅读和修改?
编程挑战
编写下面四个函数:
int getMax(int a, int b);
int getMin(int a, int b);
bool isPositive(int x);
double rectangleArea(double width, double height);然后在 main() 中输入数据并调用这些函数,分别完成:
- 求两个整数的最大值;
- 求两个整数的最小值;
- 判断一个数是不是正数;
- 计算长方形的面积。