当前位置: 首页 > news >正文

深⼊理解指针(5)[回调函数、qsort相关知识(qsort可用于各种类型变量的排序)】

目录
1. 回调函数
2. qsort相关知识(qsort可用于各种类型变量的排序)

一      回调函数

     1定义/作用:把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,(作用)⽤于对该事件或条件进⾏响应。

    2好处:(下面我们来看两个效果相同的代码,比较它们的简约程度)

代码1(未使用回调函数

 

 代码2(使用回调函数

 总结:这里我们使用回调函数,使得重复得部分得到了优化,代码变得更加简约。

二      qsort相关知识

1形式:

void qsort
(
     void* base//base->待排序数组中的首元素
     size_t num//待排序数组中的元素个数因为元素个数不可能是负数所以用size_t定义
     size_t size//待排序数组中的一个元素的大小因为一个元素的大小不可能是负数所以用        size_t定义
    int* (*cmp)(const void*,const void*)//函数指针--指针指向的函数,可用于比较base指向的数组中任何两个元素的大小。  因为用于比较的数组类型不同所以用void定义,又因为我们只对数据进行排序而不对数据进行改变所以用const修饰,防止数据被改写
    
)

2   qsort 使⽤举例

2.1使⽤qsort函数排序整型数据

#include <stdio.h>
//qosrt函数的使⽤者得实现⼀个⽐较函数int int_cmp(const void * p1, const void * p2)
{return (*( int *)p1 - *(int *) p2);
}int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
{printf( "%d ", arr[i]);
}printf("\n");
return 0;
}

2.2使⽤qsort函数排序结构数据(要指明排序类型例如描述一个人是使用结构体可能含有姓名,性别等,这时候就要指明你要排序的数据如要对姓名就要指明姓名)

按照名字来排序

 注意在按照名字进行比较时和整型有所不同,因为名字是字符串,要用strcmp函数。

按照年龄来⽐较

2.3 qsort函数的模拟【实现使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)】。

主体框架

注意我们这里要模仿qsort函数,对其冒泡排序设置参数

排序的实现

 注意这里和冒泡排序有所不同的是在于冒泡排序只对整型排序直接比较即可,而我们这里比较两个元素的大小是通过字符类型来比较因为每个整数数组中的元素都是占4个字节,所以要用强制类型转换将其转换为char*型,而这里的width表示的是整型数组中一个元素的长度,所以这里的(char*)base + j * width,和(char*)base+(j + 1) * width表示第j个元素和第j+1个元素

函数的声明

实现交换

因为一个整型占4个字节无法进行交换,这时候我们将其划分为一个一个字节,将其强制类型转换为字符型char*,然后我们只要将两个元素的4个字节一一交换即可。

 这里的n表示的是width(4),因为一个整型占4个字节,而我们前面将其强制类型转换为字符型char*,这时候我们只要将两个元素的4个字节一一交换即可。

整体代码

#include <stdio.h>int cmp_int(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2; 
}void swap(char* buf1, char* buf2, size_t n)
{int i = 0;for (i = 0; i < n; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
{int i = 0;//趟数for (i = 0; i < sz - 1; i++){//一趟内部的排序int j = 0;for (j = 0; j < sz - i - 1; j++){if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0){//判断是否满足条件,满足则进行交换swap((char*)base + j * width, (char*)base+(j + 1) * width, width);}}}
}
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}
void test()
{int arr[] = { 9,8,7,6,5,4,3,2,1,10};int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);//模仿qsort函数,对其设置参数print(arr, sz);//打印
}
int main()
{test();return 0;}

    本篇文章就到此结束,希望有所能帮到 读者更好的了解指针。


http://www.mrgr.cn/news/70660.html

相关文章:

  • 详细描述一下Elasticsearch更新和删除文档的过程?
  • 数据结构-树状数组专题(1)
  • Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行
  • CentOS 7.9 搭建本地Yum源
  • 什么是强化学习?
  • CMake + mingw + opencv
  • YOLOv11融合CVPR[2020]自校准卷积SCConv模块及相关改进思路|YOLO改进最简教程
  • 前端知识点---字符串的8种拼接方法(Javascript)
  • 边缘检测的100种方法
  • PCL 点云拟合 Ransac拟合空间球体
  • 基于图的去中心化社会推荐过滤器
  • 麒麟服务器工作站SP1 arm环境qt5.6.3源码编译
  • 【大咖云集 | IEEE计算智能学会广州分会支持】第四届信息技术与当代体育国际学术会议(TCS 2024,12月13-15日)
  • 数据库基础(14) . MySQL存储过程
  • 嵌入式学习-C嘎嘎-Day01
  • 基于stm32的智能晾衣杆(开源)
  • uniapp中webview全屏不显示导航栏解决方案
  • 20个Python自动化脚本,提升编程能力
  • 图形几何之美系列:仿射变换矩阵之先转后偏
  • 元岭村停车场的收费情况探寻
  • C#-objetc中的方法
  • mysql数据库(四)单表查询
  • 20241111_室内定位
  • 把握鸿蒙生态崛起的机遇:开发者视角的探讨
  • 应用系统开发(4)CMOS 模拟开关芯片HCF4053BE
  • CS144_01