可爱的回调函数

 

目录

一、作者声明:

二、什么回调函数?

三、库函数qsort为例,讲解回调函数


一、作者声明:

标题中的可爱纯纯是用来凑字数,没有特殊含义,因为可爱的平台不让用四个字作为标题!

如果平台允许我甚至想用两个字作为标题——《回调》!或者直接一个字——《调》!

二、什么回调函数?

通过函数指针调用的函数就是回调函数。

如果把函数的指针(地址)作为参数传给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外一方调用的,用于对该事件或条件的响应。

三、库函数qsort为例,讲解回调函数

qsort函数:快速排序函数

qsort是一个库函数,底层使用的是快速排序的方式,对数据进行排序。该函数可以直接使用,能对任意类型的数据进行排序。

包含于头文件:

#include

函数原型:

void qsort (void* base, size_t num, size_t size, int (*compar)(const void* e1,const void* e2))

参数解析:

void *base是待排序数组第一个元素的地址(起始地址)

size_t num是待排序数组的大小(元素个数)

size_t num是待排序数组元素的大小(每一个元素的字节大小)

int (*compar)(const void* e1,const void* e2)是函数指针,指向比较函数(不同类型数据的比较方法不同,因此需要自定义比较方法),该函数返回值为int类型,参数为e1,e2,分别是待比较两个元素的地址。返回值要求:

若e1指向的元素大于e2指向的元素,则返回大于0的数字;若相等,则返回0;若小于,则返回小于0的数字。

(注1:正是因为有了compar比较函数,qsort函数才能排序任意类型的数据)

(注2:void *类型指针不能直接解引用,也不能加减整数,它是用来存放任意类型数据的地址,使用时需要强制类型转换)

实例代码1(排序整型数据):

void Printnums(int* nums, size_t size)//打印整型数组函数
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		printf("%d ", nums[i]);
	}
}

int cmp_int(const void* e1, const void* e2)//整形数据的比较函数
{
	return *(int*)e1 - *(int*)e2;//无具体类型指针先强制类型转换,再解引用
}
int main()
{
	int nums[10] = { 10,9,8,7,6,5,4,3,2,1 };
	qsort(nums, sizeof(nums) / sizeof(nums[0]), sizeof(nums[0]), cmp_int);
    //待排序数组起始地址;待排序数组元素个数;待排序数组每个元素的字节大小;数据比较函数

	Printnums(nums, sizeof(nums) / sizeof(nums[0]));
	return 0;
}

实例代码2(按年龄大小排序结构体数组):

struct stu {
	char name[20];
	int age;
};

void Print_struct_age(struct stu* arr,size_t size)//打印结构体数组中结构体成员变量—年龄
{
	for (int i = 0; i < size; i++)
	{
		printf("%d ", arr[i].age);
	}
	printf("\n");
}

int cmp_struct_age(const void* e1, const void* e2)//按照年龄比较排序
{
	return ((struct stu*)e1)->age - ((struct stu*)e2)->age;//强制类型转换为结构体指针类型,不解引用利用->也可以访问成员变量
}

int main()
{
	struct stu s1 = { "Tom",29 };//结构体变量
	struct stu s2 = { "Jerry",20 };
	struct stu s3 = { "David",26 };
	struct stu arr[] = { s1,s2,s3 };//结构体数组

	Print_struct_age(arr, sizeof(arr) / sizeof(arr[0]));//打印年龄
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), cmp_struct_age);//按年龄排序
	Print_struct_age(arr, sizeof(arr) / sizeof(arr[0]));//打印年龄

	return 0;
}

 

实例代码3(按姓名首字母排序结构体数组):

struct stu {
	char name[20];
	int age;
};

void Print_struct_name(struct stu* arr,size_t size)//打印结构体数组中结构体成员变量—姓名
{
	for (int i = 0; i < size; i++)
	{
		printf("%s ", arr[i].name);
	}
	printf("\n");
}

int cmp_struct_name(const void* e1, const void* e2)
{
	return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);//利用strcmp字符串比较函数,该函数的返回值要求和qsort中compar比较函数的返回值要求相同
}

int main()
{
	struct stu s1 = { "Tom",29 };//结构体变量
	struct stu s2 = { "Siri",20 };
	struct stu s3 = { "David",26 };
	struct stu arr[] = { s1,s2,s3 };//结构体数组

	Print_struct_name(arr, sizeof(arr) / sizeof(arr[0]));//打印姓名
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), cmp_struct_name);//按姓名首字母排序
	Print_struct_name(arr, sizeof(arr) / sizeof(arr[0]));//打印姓名

	return 0;
}

可爱的回调函数_第1张图片

 

以上所有实例都是利用qsort快速排序函数对各种类型的数据排序,当我们向qsort函数参数传入比较函数compar地址时,该函数在qsort函数中通过其函数指针被调用,就是回调函数。

你可能感兴趣的:(C/C++,c语言,c++)