回调函数与qsort函数

简介: 回调函数与qsort函数

一:回调函数

1:回调函数的定义

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

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


2:回调函数应用举例-简单计算器的实现

#include<stdio.h>
void menu()
{
  printf("*****************************\n");
  printf("*****1 add   2 sub***********\n");
  printf("*****3 mul   4 div***********\n");
  printf("*****0 exit    **************\n");
  printf("*****************************\n");
}
 void calc(int (*p)(int x, int y))
{
  int ret = 0;
  int a = 0;
  int b = 0;
  printf("请输入两个操作数:");
  scanf("%d %d", &a, &b);
  ret = p(a, b);//通过p指针调用函数
  //如果输入input=1;调用的函数就是add
  //通过指针p调用add函数,add函数就称为回调函数
  printf("%d\n", ret);
}
int add(int x, int y)
{
  return x + y;
}
int sub(int x, int y)
{
  return x - y;
}
int mul(int x, int y)
{
  return x * y;
}
int div(int x, int y)
{
  return x / y;
}
int main()
{
  int input = 0;
  do
  {
    menu();
    printf("请选择:");
    scanf("%d", &input);
    switch (input)
    {
    case 1:
      calc(add);//add函数作为calc函数的参数
      break;
    case 2 :
      calc(sub);//sub函数作为calc函数的参数
      break;
    case 3:
      calc(mul);//mul函数作为calc函数的参数
      break;
    case 4:
      calc(div);//div函数作为calc函数的参数
      break;
    case 0:
      printf("退出计算器\n");
      break;
    default:
      printf("选择错误,重新选择\n");
      break;
    }
  } while (input);
  return 0;
}
*****************************
*****1 add   2 sub***********
*****3 mul   4 div***********
*****0 exit    **************
*****************************
请选择:1
请输入两个操作数:2 3
5
*****************************
*****1 add   2 sub***********
*****3 mul   4 div***********
*****0 exit    **************
*****************************
请选择:2
请输入两个操作数:4 2
2
*****************************
*****1 add   2 sub***********
*****3 mul   4 div***********
*****0 exit    **************
*****************************
请选择:3
请输入两个操作数:4 3
12
*****************************
*****1 add   2 sub***********
*****3 mul   4 div***********
*****0 exit    **************
*****************************
请选择:4
请输入两个操作数:8 4
2
*****************************
*****1 add   2 sub***********
*****3 mul   4 div***********
*****0 exit    **************
*****************************
请选择:6
选择错误,重新选择
*****************************
*****1 add   2 sub***********
*****3 mul   4 div***********
*****0 exit    **************
*****************************
请选择:0
退出计算器

二:qsort函数

qsort是一个库函数,使用时需要头文件stdlib,qsort函数用于对数据进行排序,可以排序任意类型的数据。

qsort函数有4个参数
void qsort(void* base, //base指向待排序的第一个元素的地址
         size_t num,  //待排序的元素个数(base指向空间的数组的个数)
         size_t size, //待排序的数组元素的大小,单位是字节
         int (*compar)(const void* e1, const void* e2) 
          compar是一个函数指针,指向的函数能够比较2个元素
     int (*)(const void *e1,const void* e2)是函数指针类型
void* 是一种函数指针类型,是通用指针类型,是无具体类型的指针
void* 类型的指针变量,可以接收(存放)任意数据类型的地址
因为void*是无具体类型的指针,所以不可以进行+1/-1,解引用操作

qsort函数排序举例:

#include <stdio.h>
#include <stdlib.h>
 void Print(int* arr, int sz)
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", *(arr + i));
  }
  printf("\n");
}
 int cmp_int(const void* e1, const void* e2)
 {
   return *(int*)e1 - *(int*)e2;
   //e1,e2是void*类型,而需要比较的元素是int型的整型数组,
   //所以需要强制类型转换成(int*),再解引用
 }
void test(int *arr,int sz)
{
  qsort(arr, sz, sizeof(arr[0]),cmp_int);
  //cmp_int 是个函数指针,指向的函数可以比较两个函数。
}
int main()
{
  int arr[] = { 1,2,4,6,3,7,8,5,9,10 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  Print(arr, sz);
  test(arr,sz);
  Print(arr, sz);
  return 0;
}


目录
相关文章
|
安全 编译器 Linux
精伦安全模块-身份证读卡器对接-Qt调用SDK
精伦安全模块-身份证读卡器对接-Qt调用SDK
275 0
|
Linux 编译器 C语言
Linux(3)Device Tree概念1(上)
Linux(3)Device Tree概念1
248 0
|
10月前
|
NoSQL PHP MongoDB
docker push推送自己搭建的镜像
本文详细介绍了如何搭建和复盘两个Web安全挑战环境:人力资源管理系统和邮件管理系统。首先,通过Docker搭建MongoDB和PHP环境,模拟人力资源管理系统的漏洞,包括nosql注入和文件写入等。接着,复盘了如何利用这些漏洞获取flag。邮件管理系统部分,通过目录遍历、文件恢复和字符串比较等技术,逐步绕过验证并最终获取flag。文章提供了详细的步骤和代码示例,适合安全研究人员学习和实践。
169 3
docker push推送自己搭建的镜像
|
9月前
|
分布式计算 DataWorks 大数据
🚀DataWorks 深度实践与评测:数据治理新时代的全景体验。
在数字化转型中,企业不仅需要技术创新,更需完善的**数据管理和开发治理工具**。DataWorks 作为阿里云推出的一站式智能大数据平台,整合了阿里巴巴15年的大数据经验,提供从数据接入、开发、治理到资产管理的全流程解决方案。它支持湖仓一体架构,内置AI助手提升开发效率,并适用于金融、零售等多行业。本文将深入探讨 DataWorks 的功能、应用场景及性能表现,通过用户画像分析实践展示其强大潜力...
515 8
🚀DataWorks 深度实践与评测:数据治理新时代的全景体验。
|
Kubernetes 数据安全/隐私保护 数据中心
如何在 Kubernetes 中使用命名空间
【8月更文挑战第11天】
619 0
如何在 Kubernetes 中使用命名空间
|
存储 分布式计算 Hadoop
ChunkServer 在分布式文件系统中的角色
【8月更文第30天】随着大数据处理需求的增长,分布式文件系统(Distributed File System, DFS)成为了处理大规模数据集的标准工具。在众多分布式文件系统中,Hadoop 分布式文件系统(HDFS)是最著名的一种。HDFS 采用主从架构,其中 NameNode 负责管理文件系统的命名空间和客户端对文件的访问,而 DataNodes(也称为 ChunkServers)负责存储实际的数据块。本文将深入探讨 ChunkServer 在 HDFS 中的角色和重要性,并通过代码示例展示其在系统中的具体功能。
142 0
|
PHP 数据库 开发者
探索PHP的现代演变:从Web开发到框架创新
【8月更文挑战第13天】本文将深入探讨PHP语言自诞生以来的发展历程,特别是它在Web开发领域的演进和在现代框架中的创新。我们将回顾PHP的历史,分析其在不同阶段面临的挑战及解决方案,并讨论PHP如何适应新的编程范式和技术需求,以及这些变化对开发者社区的影响。
105 2
|
消息中间件 存储 Cloud Native
ApsaraMQ Serverless 演进之路,助力企业降本
ApsaraMQ Serverless 演进之路,助力企业降本
104033 77
|
SQL 分布式计算 Hadoop
Hive on Tez 的安装配置
Hive on Tez 的安装配置
873 0
Hive on Tez 的安装配置
|
传感器 人工智能 监控
物联网行业解决方案(四)
物联网行业解决方案(四)
467 8