函数指针和回调函数
函数指针
函数指针概括
函数的二进制代码存放在内存四区的代码段,函数的地址是它在内存中的起始地址。如果把函数地址作为参数传递给函数,那么这个函数就可以调用传递进来的地址所指向的函数。
使用函数指针三个步骤
- 声明函数指针
- 让函数指针指向函数的地址
- 使用函数指针调用函数
声明函数指针
声明普通指针时,必须提供指针的类型。同样,声明函数指针时,也必须提供函数的返回类型和参数列表(函数名,形参名可有可无)。
函数原型
int func1(int id, string str);
int func2(int no, string message);
int func3(int index, string info);
int funcx(int xxx, string yyy);
bool func5(int idx, string info);
bool func6(int iii);
上述函数中,总共三个函数类型func1,fun2,fun3,funx
返回值和参数类型相同则是同类型。fun5和func6
分别属于不同的函数类型。
函数指针形式一
返回类型(*函数名)(参数列表)
三种函数类型的函数指针声明如下
int (*pfa)(int, string); // fun1,fun2,fun3,funx
bool (*pfb)(int, string); // fun5
bool (*pfc)(int); // fun6
回调函数
回调函数概括
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
简单案例展示一
#include <iostream>
using namespace std;
void func(int no, string str)
{
cout << "今天是星期" << no << "," << str << endl;
}
int main()
{
int day1 = 7;
string str1 = "还在上班,不开心......";
// 正常调用函数
func(day1, str1);
// 使用函数指针调用函数
void (*pfun)(int, string);
pfun = func;
pfun(day1, str1); // 直接用函数名调用
(*pfun)(day1, str1);// 使用(*函数名)调用
}
效果展示
今天是星期7,还在上班,不开心......
今天是星期7,还在上班,不开心......
今天是星期7,还在上班,不开心......
简单案例展示二
假设有一场考试,要测试所有学生的成绩。每个学生的做题习惯和考试风格不同。考试的流程由我们来控制,考生的发挥和老师的评定则由自己来定。
函数指针形式二,typedef
定义函数指针类型
typedef 返回类型(*新类型)(参数列表)
简单代码实现如下:
#include <iostream>
using namespace std;
// 考生个人发挥函数
void studentDoing(int iii)
{
// 自定义
cout << "考生" << iii << "完成答卷..." << endl;
}
// 监考老师控制考场函数
void teacher1Doing(int iii, int jjj)
{
// 自定义
cout << "监考老师" << iii << "和" << jjj << "进行监考..." << endl;
}
// 任课老师批改成绩函数
void teacher2Doing(string str)
{
// 自定义
cout << "任课老师批改试卷...," << str << endl;
}
typedef void(*FUNC_SRUDENT)(int);
typedef void(*FUNC_TEACHER1)(int, int);
typedef void(*FUNC_TEACHER2)(string);
// 组织学生考试函数
void examination(FUNC_SRUDENT p1, FUNC_TEACHER1 p2, FUNC_TEACHER2 p3, int iii, int jjj, int kkk, string str)
{
// 调用监考老师控制考场函数
p2(jjj, kkk);
// 调用考生个人发挥函数
p1(iii);
// 调用任课老师批改成绩函数
p3(str);
}
int main()
{
cout << "考试开始" << endl;
FUNC_SRUDENT _p1;
FUNC_TEACHER1 _p2;
FUNC_TEACHER2 _p3;
_p1 = studentDoing;
_p2 = teacher1Doing;
_p3 = teacher2Doing;
examination(_p1, _p2, _p3, 1, 12, 13, "改卷子真累啊");
examination(_p1, _p2, _p3, 2, 12, 13, "改卷子真累啊");
examination(_p1, _p2, _p3, 3, 12, 13, "终于改完了啊");
cout << "公式成绩" << endl;
}
在这个案例中,我们定义了三个函数指针FUNC_SRUDENT, FUNC_TEACHER1, FUNC_TEACHER2
,分别指向考生个人发挥函数、监考老师控制考场函数和任课老师批改成绩函数。然后,我们通过函数指针来调用这三个函数。这三个指针被examination
函数调用,我们可以说这三个函数就是回调函数。
代码运行如下
考试开始
监考老师12和13进行监考...
考生1完成答卷...
任课老师批改试卷...,改卷子真累啊
监考老师12和13进行监考...
考生2完成答卷...
任课老师批改试卷...,改卷子真累啊
监考老师12和13进行监考...
考生3完成答卷...
任课老师批改试卷...,终于改完了啊
公式成绩