1、概述。
我们在C/C++编程中经常涉及到回调函数。
回调函数到底是什么呢?回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。例如,我们在win32开发里面,使用windows API时遇到的WinProc()函数,就是我们编写而由操作系统调用的函数。
2、实例
2.1 关键知识点。
一般格式: 返回值 (*指针名) (参数列表)。
作用域: 全局。
2.2 自己的回调。
在此例中,我们定义一个Person结构保存基本信息,然后创建回调,通过比较数据对象做出展示效果。
2.2.1 定义数据结构:
1
2
3
4
5
6
7
8
9 1struct Person
2{
3 string name;
4 string sex;
5 int age;
6 int id;
7};
8
9
2.2.2 定义函数指针:
1
2
3 1typedef bool(*pCallBack)(Person, Person);
2
3
2.2.3 定义主调函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 1void BubbleSort(vector<Person> arr, pCallBack func)
2{
3 const int nSize = arr.size();
4 Person pers{};
5 for (int i = 0; i < nSize; i++)
6 {
7 for (int j = 0; j < nSize - i - 1; j++)
8 {
9 if ((*func)(arr[j], arr[j + 1]))
10 {
11 pers = arr[j];
12 arr[j] = arr[j + 1];
13 arr[j + 1] = pers;
14 }
15 }
16 }
17
18 for (auto it:arr)
19 {
20 cout << it.name << "\t" << it.age << "\t" << it.id << endl;
21 }
22}
23
24
2.2.4 定义比较增长因子及设置接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 1bool g_bIncrease = true;
2
3void SetIncrease(bool bIncrease = true);
4
5void SetIncrease(bool bIncrease)
6{
7 g_bIncrease = bIncrease;
8 if (bIncrease)
9 {
10 cout << "从小到大:" << endl;
11 }
12 else
13 {
14 cout << "从大到小:" << endl;
15 }
16}
17
18
2.2.5 定义两种比较方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 1//比较年龄
2bool CompareAge(Person per1, Person per2)
3{
4 if (g_bIncrease)
5 {
6 if (per1.age > per2.age)
7 {
8 return true;
9 }
10 return false;
11 }
12 else
13 {
14 if (per1.age < per2.age)
15 {
16 return true;
17 }
18 return false;
19 }
20}
21//比较ID
22bool CompareId(Person per1, Person per2)
23{
24 if (g_bIncrease)
25 {
26 if (per1.id > per2.id)
27 {
28 return true;
29 }
30 return false;
31 }
32 else
33 {
34 if (per1.id <= per2.id)
35 {
36 return true;
37 }
38 return false;
39 }
40}
41
42
2.2.6 主程序调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 1int main()
2{
3 vector<Person> arr;
4 Person per;
5 per.name = "Gon";
6 per.sex = "boy";
7 per.age = 12;
8 per.id = 456325452;
9 arr.push_back(per);
10 per.name = "Killua";
11 per.sex = "girl";
12 per.age = 33;
13 per.id = 123254128;
14 arr.push_back(per);
15 per.name = "Kula";
16 per.sex = "boy";
17 per.age = 8;
18 per.id = 965754125;
19 arr.push_back(per);
20 per.name = "Leiouli";
21 per.sex = "girl";
22 per.age = 41;
23 per.id = 789652484;
24 arr.push_back(per);
25
26 cout << "初始数据:" << endl;
27 Show(arr);
28
29 cout << "\n\n";
30 cout << "age";
31 SetIncrease(false);
32 BubbleSort(arr, (pCallBack)CompareAge);
33 cout << "\n\n";
34 cout << "id";
35 SetIncrease(true);
36 BubbleSort(arr, (pCallBack)CompareId);
37
38 cin.get();
39 return 0;
40}
41
42
2.2.7 运行效果:
2.3 系统的回调。
在这个实例中,需要学习系统快排函数qsort(),来加深回调的理解。
2.3.1 首先,添加头文件 #include “stdlib.h”
2.3.2 然后,F12看看函数声明:
1
2
3
4
5
6
7
8 1_CRTIMP void __cdecl qsort(
2_Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void * _Base,
3 _In_ size_t _NumOfElements,
4 _In_ size_t _SizeOfElements,
5 _In_ int (__cdecl * _PtFuncCompare)(const void *, const void *)
6 );
7
8
参数一: 传进来需要排序的地址
参数二: 参与排序的数量。
参数三: 参与排序的每一个元素的空间大小。
参数四: 函数指针,确立升序还是降序。
2.3.3 接着,定义新的函数指针:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 1int CompareAgeII(const void* per1, const void* per2)
2{
3 Person* pers1 = (Person*)per1;
4 Person* pers2 = (Person*)per2;
5
6 if (g_bIncrease)
7 {
8 if (pers1->age > pers2->age)
9 {
10 return 1;
11 }
12 return -1;
13 }
14 else
15 {
16 if (pers1->age <= pers2->age)
17 {
18 return 1;
19 }
20 return -1;
21 }
22}
23
24
2.3.4 现在,主程序调用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 1int main()
2{
3 vector<Person> arr;
4 Person per;
5 per.name = "Gon";
6 per.sex = "boy";
7 per.age = 12;
8 per.id = 456325452;
9 arr.push_back(per);
10 per.name = "Killua";
11 per.sex = "girl";
12 per.age = 33;
13 per.id = 123254128;
14 arr.push_back(per);
15 per.name = "Kula";
16 per.sex = "boy";
17 per.age = 8;
18 per.id = 965754125;
19 arr.push_back(per);
20 per.name = "Leiouli";
21 per.sex = "girl";
22 per.age = 41;
23 per.id = 789652484;
24 arr.push_back(per);
25
26 cout << "初始数据:" << endl;
27 Show(arr);
28
29 cout << "\n" << "系统快排,age";
30 SetIncrease(false);
31 qsort(arr.data(), arr.size(), sizeof(Person), CompareAgeII);
32 Show(arr);
33 cin.get();
34 return 0;
35}
36
37
2.3.5 最后,运行:
3、总结.
①、定义函数指针,形如:typedef bool(*pCallBack)(Person, Person);
②、定义当做形参的普通函数,形如:bool CompareAge(Person per1, Person per2);
③、定义主调函数,形如:void BubbleSort(vector<Person> arr, pCallBack func);
④、调用回调函数,形如:BubbleSort(arr, (pCallBack)CompareAge);