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

C语言 — qsort 函数

介绍:
qsort是一个库函数,用来对数据进行排序,可以排序任意类型的数据。

void qsort (void*base, size_t num,  size_t size,  int(*compart)(const void*,constvoid*) )

qsort 具有四个参数:

  • base 指向待排序的第一个元素,也就是第一个元素的地址。
  • num 待排序的元素个数。
  • size  待排序的元素的字节数大小。
  • compart 是一个函数指针,指向的函数能够比较两个元素。

其中compart 是进行排序的调用函数。

int(*compart)(const void*,const void*)  里面的两个vodi*指向需要排序的元素,也可以写为int(*compart)(const void*e1, const void*e2)

int(*)(const void*,const void*) 是compart的函数指针变量类型。

进行函数调用的时候,compart的返回类型是int 进行调用的参数是void* 类型的指针

void*  :

void* 是一种指针类型  void*是一种通用指针类型,void*类型的指针变量,可以接受任意数据类型的地址。

例如:
int a = 10;
int*p = &a;
char*pc = &a;//会出错,因为类型不同
void*pv = &a;//并不会出现报错
但是void* 还是有缺陷,列如:pv++;pv+1;*pv;都会出错。
因为是通用类型或者说是无具体类型的指针,导致进行访问下一个地址时或者解引用时,不知道增加或者解引用多少个字节。
所以当void*pv使用pv++;pv+1;*pv;时会报错。

至于qsort中为什么使用void*,是因为不知道会有什么类型进行排序,或者说为了许多类型的都能进行排序,才使用void*

用法:
 

cmp_t 要能够比较 e1和 e2 指向的两个元素,并且给出返回值。

而返回值也是有规定的,如果e1>e2 返回一个比0大的数,e1和e2一样大返回0,e1<e2 返回一个比0小的数。

 

e1和e2指向的元素进行比较大小,实际上就是*e1和*e2进行比较大小,但是二者都是void * 类型,无法进行*的解引用操作,所以需要进行强制类型转化。

而*(int*)e1 就是将e1的指针类型void*强制转化为int* 并且进行*解引用

而后面return 进行的则是比较大小,当e1大于e2时,相减是大于0的数,返回也是大于0的数

e1等于e2则相减是等于0,返回也是0

e1小于e2相减则是小于0的数,返回也是小于0的数

本质上 compart也是一种回调函数,且是有具体规定的回调函数——qsort内部调动compart这个函数

而具体规定就是int(*compart)(const void*e1, const void*e2)

除了compart这个函数名可以变外,其他必须一致。

compart 单独调用出来就是因为不同的数据类型有着不同的比较方式和方法,所以需要独立出来进行函数调用。

例如:

结构体的比较:int compart_age(const void* e1, const void* e2)
{return ((struct stu*)e1)->age - ((struct stu*)e2)->age;}
void test2()
{struct stu s[] = { {"zgabfsab",20},{"lisi",30},{"wangwu",15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), compart_age);}
int main()
{test2();return 0;
}
整型数组的比较:int cmp_int(const void* e1, const void* e2)
{return *(int*)e1- *(int*)e2;
}
void test1()
{int arr[] = { 3, 1, 5, 7, 2, 4, 8, 6, 0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr,sz,sizeof(arr[0]), cmp_int);}
int main()
{test1();return 0;
}
http://www.lryc.cn/news/124925.html

相关文章:

  • 开放式耳机哪个好一点?推荐几款优秀的开放式耳机
  • vue-cli前端工程化——创建vue-cli工程 router版本的创建 目录结构 案例初步
  • Go和Java实现外观模式
  • 人工智能(一)基本概念
  • 〔AI 绘画〕Stable Diffusion 之 解决绘制多人或面部很小的人物时面部崩坏问题 篇
  • 初步认识OSI/TCP/IP一(第三十八课)
  • 英伟达结构化剪枝工具Nvidia Apex Automatic Sparsity [ASP](2)——代码分析
  • FileNotFoundError: [WinError 2] 系统找不到指定的文件。
  • Linux: sysctl:net: IPV4_DEVCONF_ALL ignore_routes_with_linkdown; all vs default
  • 光耦继电器:实现电气隔离的卓越选择
  • 鸿蒙开发学习笔记2——实现页面之间跳转
  • 电子商务类网站需要什么配置的服务器?
  • table 根据窗口缩放,自适应
  • 应急响应-Webshell
  • 【调整奇数偶数顺序】
  • Linux(Ubuntu)系统临时IP以及静态IP配置(关闭、启动网卡等操作)
  • 2023-08-11 LeetCode每日一题(矩阵对角线元素的和)
  • Github 80 个键盘快捷键和一些搜索技巧的备忘清单
  • 神经网络基础-神经网络补充概念-08-逻辑回归中的梯度下降算法
  • npm ERR! cb.apply is not a function
  • iShot Pro for Mac 2.3.9最新中文版
  • FiboSearch Pro – Ajax Search for WooCommerce 商城AJAX实时搜索插件
  • k8s dns 解析service异常
  • P6464 [传智杯 #2 决赛] 传送门
  • 如何通过CSS选择器选择一个元素的子元素?如何选择第一个子元素和最后一个子元素?
  • 智能家居(2)---串口通信(语音识别)控制线程封装
  • MySql主从复制1032错误(Slave_IO_Running: Yes Slave_SQL_Running: No)
  • 毕业论文格式设置总结
  • 7-3 整数四则运算
  • React 全栈体系(一)