回调函数,以qsort函数为例

简介: 回调函数,以qsort函数为例
一、作者声明:

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

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

二、什么回调函数?

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

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

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

qsort函数:快速排序函数

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

包含于头文件:

#include<stdlib.h>

函数原型:

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

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

目录
相关文章
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
496 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
Go 开发工具 Python
【开发工具】Goland 2022.4 破解(by ja-netfilter)
【开发工具】Goland 2022.4 破解(by ja-netfilter)
881 1
【开发工具】Goland 2022.4 破解(by ja-netfilter)
|
智能硬件
搭建Home Assistant智能家居系统 - 随时随地控制你的家庭设备「内网穿透」(三)
搭建Home Assistant智能家居系统 - 随时随地控制你的家庭设备「内网穿透」
564 0
|
测试技术 计算机视觉
斯坦福新研究提升大模型长视频理解能力
【2月更文挑战第29天】斯坦福大学研究团队开发的VideoAgent系统在长视频理解上取得突破,提升了大型语言模型处理视频内容的能力。该系统通过模拟人类认知过程,以高效(平均8.4帧)实现高准确率(54.1%和71.3%的零样本准确率),在EgoSchema和NExT-QA基准测试中超越现有最佳方法。VideoAgent借鉴人类观看视频的方式,迭代选择关键帧进行信息提取和推理,为长视频理解设定新标准。论文链接:[arxiv.org/pdf/2403.10517.pdf](https://arxiv.org/pdf/2403.10517.pdf)
443 1
斯坦福新研究提升大模型长视频理解能力
HTML中如何插入空格,HTML空格代码,多种HTML空格写法
HTML中如何插入空格,HTML空格代码,多种HTML空格写法
389 0
|
机器学习/深度学习 Python 算法框架/工具
Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(一)(1)
Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(一)
209 0
Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(一)(1)
|
SQL Java 数据库连接
|
存储 监控 关系型数据库
|
网络安全 虚拟化 Windows
VMware创建和使用虚拟网络
VMware创建和使用虚拟网络
453 0
VMware创建和使用虚拟网络