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

qsort :超级打包工

你可以把qsort想象成一个**“超级打包工”**。

它的绝活是能把一堆乱七八糟的东西(数组)排得整整齐齐。但它有个“怪癖”:它力气很大,能搬任何东西(整数、小数、结构体),但它不认识这些东西,不知道谁大谁小。

所以,每次用它干活,你都得配一个**“指导员”**(比较函数),告诉它:“嘿,这两个东西,谁应该放前面?”

1. 怎么“雇佣”这个打包工?(函数原型)

要请qsort帮忙,你得把话说全了,一共要给它 4 个信息:

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

这 4 个参数翻译成人话就是:

  1. base(基地):要排序的数组,从哪儿开始?(传数组首地址)。
  2. num(人数):一共有多少个元素要排?
  3. size(体型):每个元素占多大内存?(比如int是 4 字节,用sizeof(int))。
  4. compar(指导员):这是一个函数指针。你得把你自己写的比较函数的地址传给它。

2. 怎么写“指导员”?(比较函数)

这是新手最容易晕的地方。qsort会拿着数组里的两个元素的地址,去问你的“指导员”函数:“这俩谁大?”

标准模板:

int cmp_function(const void* e1, const void* e2) { 你的逻辑 }

核心规则(死记硬背版):

  • 如果e1e2大,返回正数(> 0)。
  • 如果e1e2小,返回负数(< 0)。
  • 如果e1等于e2,返回0
  • 要注意的是qsort是默认升序的。

这就是为什么qsort函数的第四个参数的函数指针所指向的函数的返回类型是int

实战技巧(整型排序):
如果是排整数,想从小到大排,直接做减法最简单:
return *(int*)e1 - *(int*)e2;
(注意:这里必须先把void*强转成int*,再解引用取值,因为void指针不能解引用)

3. 一个完整的栗子(排序整数)

假设我们要把{ 9, 3, 5, 1 }排个序。

#include <stdio.h> #include <stdlib.h> qsort 在这里面 第一步:写个指导员函数(从小到大) int int_cmp(const void* e1, const void* e2) { 强转类型,然后做减法 return *(int*)e1 - *(int*)e2; } int main() { int arr[] = { 9, 3, 5, 1 }; int sz = sizeof(arr) / sizeof(arr[0]); 算出有4个元素 第二步:雇佣 qsort 参数1:数组名(首地址) 参数2:元素个数 (4) 参数3:单个元素大小 (4字节) 参数4:比较函数的名字(地址) qsort(arr, sz, sizeof(int), int_cmp); 打印看看 for(int i = 0; i < sz; i++) { printf("%d ", arr[i]); } 输出结果:1 3 5 9 return 0; }

4. 避坑指南(重点!)

  1. void是个“瞎子”*:
    qsort传给你的e1e2都是void*类型。你不能直接对它们解引用(比如*e1是错的),也不能直接加减(e1+1是错的
    )。
    必须先“整容”(强制类型转换)
    比如你要比整数,就得先写成(int*)e1,然后再*(int*)e1取值。

  2. 结构体怎么排?
    如果数组里是学生结构体,你想按年龄排。
    你的比较函数里,就要把void*转成struct Stu*,然后比较->age
    return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;

  3. 字符串类型的数据要用strcmp,详见:strcmp介绍

总结一下:
qsort负责干活(搬运、交换),你负责动脑(写比较逻辑)。只要你的比较函数写对了,它就能帮你排任何数据!

http://www.gsyq.cn/news/1582030.html

相关文章:

  • 技术深度解析:1Panel批量操作架构设计与多服务器并行管理实战
  • 外包工日常管理合规指南:从合同到结算,SaaS系统如何嵌入控制点
  • 西门子 CU240E-2 PN 控制单元专业维修服务
  • AI电商工具测评!商品图片AI味太重怎么办?试试这些工具
  • AI写论文工具深度测评:通用大模型与专业工具的真实表
  • [STM32 HAL库][定时器]PWM实验笔记
  • C++ 利用Clock类和Date类定义一个带日期的时钟类ClockWithDate,且对该对象能进行增加秒数的操作
  • 古韵楚风,诗意天成——探寻《诗经》《楚辞》中的绝美名字
  • 微软把 Windows 计算器开源了,3 万 Star 背后藏着什么
  • CocoaHTTPServer:为Apple生态系统构建的嵌入式HTTP服务器框架
  • 快慢指针巧解链表环检测(多解)
  • 2026燕麦奶口碑排行:营养师推荐清单来了
  • 红日靶场二:WebLogic CVE-2019-2725 到域控沦陷全流程
  • 桑坦德银行向全体员工开放AI工具,首季创造3500万欧元价值
  • 别再问 AMD 显卡能不能跑 AI,SGLang 加 TileLang 组合拳给你答案
  • 中小企业怎么做GEO优化?AI时代低成本长效获客指南
  • HIP 算子兼容性排查,AMD 显卡微调中那些奇怪的报错与解法
  • MateClaw v1.6.0 发布:补齐企业 Agent 工程能力,多方面升级助力生产环境
  • 多派生与多继承演示职读类StuTeech
  • AVR单片机内部温度传感器校准指南:从原理到单点/两点校准实践
  • Windows下载教程 Windows 10 保姆级安装步骤(附镜像文件)系统重装图文详解
  • GLM-5.2 vs GPT-5.5 成本实算:每天 1 万/10 万/100 万次请求的账单差距(2026)
  • 掉发和白发同时出现?高仕星维生素b的双重营养方案
  • 零代码组态开发实操:串口屏项目从数月迭代压缩至数天
  • ATtiny20 8位MCU超低功耗设计实战:从架构解析到物联网终端应用
  • 2026实战:用Gemini镜像站解决Spring Boot微服务性能瓶颈与故障排查
  • AT21CSMK100单线EEPROM开发指南:从1-Wire协议到嵌入式存储实战
  • 挖掘 Github 宝藏,盘点那些好用的 ROCm 开源项目
  • 简单好用,一键搜索全网资源!
  • windows经典漏洞之永恒之蓝