C++回调函数

本文深入探讨了C/C++中的回调函数概念,通过具体实例展示了如何定义和使用回调函数进行数据排序,包括自定义回调和系统提供的回调函数qsort()的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、概述。

我们在C/C++编程中经常涉及到回调函数。
回调函数到底是什么呢?回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。例如,我们在win32开发里面,使用windows API时遇到的WinProc()函数,就是我们编写而由操作系统调用的函数。

2、实例

2.1 关键知识点。

一般格式: 返回值 (*指针名) (参数列表)。
作用域: 全局。

2.2 自己的回调。

在此例中,我们定义一个Person结构保存基本信息,然后创建回调,通过比较数据对象做出展示效果。

2.2.1 定义数据结构:

struct Person
{
	string name;
	string sex;
	int age;
	int id;
};

2.2.2 定义函数指针:

typedef bool(*pCallBack)(Person, Person);

2.2.3 定义主调函数:

void BubbleSort(vector<Person> arr, pCallBack func)
{
	const int nSize = arr.size();
	Person pers{};
	for (int i = 0; i < nSize; i++)
	{
		for (int j = 0; j < nSize - i - 1; j++)
		{
			if ((*func)(arr[j], arr[j + 1]))
			{
				pers = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = pers;
			}
		}
	}

	for (auto it:arr)
	{
		cout << it.name << "\t" << it.age << "\t" << it.id << endl;
	}
}

2.2.4 定义比较增长因子及设置接口:

bool g_bIncrease = true;

void SetIncrease(bool bIncrease = true);

void SetIncrease(bool bIncrease)
{
	g_bIncrease = bIncrease;
	if (bIncrease)
	{
		cout << "从小到大:" << endl;
	}
	else
	{
		cout << "从大到小:" << endl;
	}
}

2.2.5 定义两种比较方法:

//比较年龄
bool CompareAge(Person per1, Person per2)
{
	if (g_bIncrease)
	{
		if (per1.age > per2.age)
		{
			return true;
		}
		return false;
	}
	else
	{
		if (per1.age < per2.age)
		{
			return true;
		}
		return false;
	}
}
//比较ID
bool CompareId(Person per1, Person per2)
{
	if (g_bIncrease)
	{
		if (per1.id > per2.id)
		{
			return true;
		}
		return false;
	}
	else
	{
		if (per1.id <= per2.id)
		{
			return true;
		}
		return false;
	}
}

2.2.6 主程序调用:

int main()
{
	vector<Person> arr;
	Person per;
	per.name = "Gon";
	per.sex = "boy";
	per.age = 12;
	per.id = 456325452;
	arr.push_back(per);
	per.name = "Killua";
	per.sex = "girl";
	per.age = 33;
	per.id = 123254128;
	arr.push_back(per);
	per.name = "Kula";
	per.sex = "boy";
	per.age = 8;
	per.id = 965754125;
	arr.push_back(per);
	per.name = "Leiouli";
	per.sex = "girl";
	per.age = 41;
	per.id = 789652484;
	arr.push_back(per);
	
	cout << "初始数据:" << endl;
	Show(arr);

	cout << "\n\n";
	cout << "age";
	SetIncrease(false);
	BubbleSort(arr, (pCallBack)CompareAge);
	cout << "\n\n";
	cout << "id";
	SetIncrease(true);
	BubbleSort(arr, (pCallBack)CompareId);

	cin.get();
	return 0;
}

2.2.7 运行效果:
在这里插入图片描述
2.3 系统的回调。

在这个实例中,需要学习系统快排函数qsort(),来加深回调的理解。

2.3.1 首先,添加头文件 #include “stdlib.h”

2.3.2 然后,F12看看函数声明:

_CRTIMP void __cdecl qsort(
_Inout_updates_bytes_(_NumOfElements * _SizeOfElements) void * _Base,
        _In_ size_t _NumOfElements,
         _In_ size_t _SizeOfElements,
        _In_ int (__cdecl * _PtFuncCompare)(const void *, const void *)
        );

参数一: 传进来需要排序的地址
参数二: 参与排序的数量。
参数三: 参与排序的每一个元素的空间大小。
参数四: 函数指针,确立升序还是降序。

2.3.3 接着,定义新的函数指针:

int CompareAgeII(const void* per1, const void* per2)
{
	Person* pers1 = (Person*)per1;
	Person* pers2 = (Person*)per2;

	if (g_bIncrease)
	{
		if (pers1->age > pers2->age)
		{
			return 1;
		}
		return -1;
	}
	else
	{
		if (pers1->age <= pers2->age)
		{
			return 1;
		}
		return -1;
	}
}

2.3.4 现在,主程序调用:

int main()
{
	vector<Person> arr;
	Person per;
	per.name = "Gon";
	per.sex = "boy";
	per.age = 12;
	per.id = 456325452;
	arr.push_back(per);
	per.name = "Killua";
	per.sex = "girl";
	per.age = 33;
	per.id = 123254128;
	arr.push_back(per);
	per.name = "Kula";
	per.sex = "boy";
	per.age = 8;
	per.id = 965754125;
	arr.push_back(per);
	per.name = "Leiouli";
	per.sex = "girl";
	per.age = 41;
	per.id = 789652484;
	arr.push_back(per);

	cout << "初始数据:" << endl;
	Show(arr);
	
	cout << "\n" << "系统快排,age";
	SetIncrease(false);
	qsort(arr.data(), arr.size(), sizeof(Person), CompareAgeII);
	Show(arr);
	cin.get();
	return 0;
}

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);

参考文章:https://www.cnblogs.com/tinaluo/p/8327880.html

入门萌新,浅知拙见,若有斧正,不胜感激。^ - ^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值