C语言:qsort的使用方法

目录

1. qsort是什么?

2. 为什么要使用qsort

3. qsort的使用

3.1 qsort的返回值和参数

3.2 qsort的compare函数参数

3.3 int类型数组的qsort完整代码

4. qsort完整代码


1. qsort是什么?

qsort中的q在英语中是quick,快速的意思了,sort就是排序,故名为快速排序

2. 为什么要使用qsort

它和冒泡排序都能帮助我们排好序,为什么要使用快速排序

因为它快速,在数据量很大的时候我们用快速排序的效率是非常高的

并且它不仅可以用于计算机的内置类型(int、double、float、char......)

而且还可以用于自己定义的类型(结构体、枚举......)

3. qsort的使用

首先,要想使用qsort需要包含头文件 stdlib.h,然后就可以使用了

先来看看qsort的返回值和参数

3.1 qsort的返回值和参数

base为你要排序数组的首地址,类型为void*

因为qsort的开发人员并不知道你需要排序的是一个整型数组还是浮点型数组还是字符串,

所以这个指针不能写死为某一个类型,而是用来void*,void* 可以用来接受任何的类型,但它不能进行加减或者解引用运算,有利有弊

num为需要排序数组的大小,类型为size_t,无符号整型,大小只能为正或0不能为负

size为数组一个元素的字节大小,类型为size_t,也是只能为正或0不能为负 

最后一个compar为一个函数指针,函数返回值为int类型,里面的参数是两个const void*

compare是用来比较两个数字(字符)的大小,从而进行排序

如果对这个参数不是很了解可以看看我之前写的文章有写到函数指针和函数指针数组

C语言:指针的进阶讲解-CSDN博客

3.2 qsort的compare函数参数

这个compare函数是需要我们自己写的,是的,就是这么麻烦,但是熟悉之后这个函数很容易就能写的出来

因为创造者并不知道我们需要排的是个什么数组,只有我们使用者才知道,所以创造者只能用你给的一些参数的信息来使用qsort进行排序

int Compare(const void* a, const void* b)
{return *(int*)a - *(int*)b;
}

 这是一个用于排序整型的compare函数

首先要写出这个函数我们的返回值和参数必须要跟它需要的一样

我们要比较两个数字的大小,那么我们首先要对这两个void类型的指针解引用拿到地址里面的值才能进行比较,最后返回一个正数或者负数

但是我们知道void* 是不能进行解引用操作的,所以我们必须得要先把这两个参数强制类型转换为int* 然后才能进行解引用操作拿到里面的值最后进行比较返回正数或者负数即可

3.3 int类型数组的qsort完整代码

#include <stdio.h>
#include <stdlib.h>void Print(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}
}int Compare(const void* a, const void* b)
{return *(int*)a - *(int*)b;
}int main()
{int arr[] = { 1,4,5,7,2,3,6,9,8,0 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), Compare);Print(arr, sz);return 0;
}

 3.4 char类型数组的qsort完整代码

 字符compare也是类似,但还是有很多细节要改变

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void Print(char* arr, int n)
{for (int i = 0; i < n; i++){printf("%c ", arr[i]);}
}int Compare(const void* a, const void* b)
{return strcmp((char*)a, (char*)b);
}int main()
{char arr[] = "bdeafcg";int sz = strlen(arr);qsort(arr, sz, sizeof(arr[0]), Compare);Print(arr, sz);return 0;
}

首先我们需要引用string.h头文件使用一些关于字符串操作的函数

数组个数sz的计算不能是前面整型的那种方式了,需要用库函数strlen计算数组大小

在比较函数里需要使用strcmp比较两个字符,这里面不需要解引用,因为这个strcmp的两个参数都是需要指针,所以传地址即可

qsort甚至还可以用于结构体

具体需要可以看以下完整代码

4. qsort完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct student
{char name[20];int age;
}STU;int compare1(void* a, void* b)
{return *(int*)a - *(int*)b;
}int compare2(void* a, void* b)
{return strcmp((char*)a, (char*)b);
}int compare3(void* a, void* b)
{return *(float*)a - *(float*)b;
}int compare4(void* a, void* b)
{return strcmp(((STU*)a)->name, ((STU*)b)->name);
}int compare5(void* a, void* b)
{return ((STU*)a)->age - ((STU*)b)->age;
}void print1(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}
}void print2(char* arr, int n)
{for (int i = 0; i < n; i++){printf("%c ", arr[i]);}
}void print3(float* arr, int n)
{for (int i = 0; i < n; i++){printf("%.2f ", arr[i]);}
}void print4(STU* arr, int n)
{for (int i = 0; i < n; i++){printf("%s ", arr[i].name);}
}void print5(STU* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i].age);}
}void test1()
{int arr[] = { 9,6,3,5,8,2,1,7,4 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), compare1);print1(arr, sz);
}void test2()
{char arr[] = "fdghabce";int sz = strlen(arr);qsort(arr, sz, sizeof(arr[0]), compare2);print2(arr, sz);
}void test3()
{float arr[] = { 1.1,0.5,3.14,9.4,10.5,1.7 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), compare3);print3(arr, sz);
}void test4()
{STU arr[] = { {"zhangsan", 26}, {"lisi", 56}, {"wangwu", 18} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), compare4);print4(arr, sz);
}void test5()
{STU arr[] = { {"zhangsan", 26}, {"lisi", 56}, {"wangwu", 18} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), compare5);print5(arr, sz);
}int main()
{//test1();//test2();//test3();//test4();test5();return 0;
}


感谢观看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/721962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++基础2:C++基本数据类型和控制结构

此专栏为移动机器人知识体系下的编程语言中的 C {\rm C} C从入门到深入的专栏&#xff0c;参考书籍&#xff1a;《深入浅出 C {\rm C} C》(马晓锐)和《从 C {\rm C} C到 C {\rm C} C精通面向对象编程》(曾凡锋等)。 2.C基本数据类型和控制结构 2.1 C基本数据类型 程序是由算法…

C# 中 Replace 字符串操作方法

在 C# 中&#xff0c;Replace 是一个字符串操作方法&#xff0c;用于替换字符串中的指定字符或子字符串。它接受两个参数&#xff1a;要查找和替换的字符串。Replace 方法在源字符串中查找所有匹配的字符或子字符串&#xff0c;并用指定的替换字符串进行替换。 下面是 Replace…

【论文精读】Mask R-CNN

摘要 基于Faster RCNN&#xff0c;做出如下改变&#xff1a; 添加了用于预测每个感兴趣区域(RoI)上的分割掩码分支&#xff0c;与用于分类和边界框回归的分支并行。mask分支是一个应用于每个RoI的FCN&#xff0c;以像素到像素的方式预测分割掩码&#xff0c;只增加了很小的计…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:点击回弹效果)

设置组件点击时回弹效果。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 clickEffect clickEffect(value: ClickEffect | null) 设置当前组件点击回弹效果。 系统能力&#xff1a; SystemCapabilit…

表达式和语句

本文参考C Primer Plus进行C语言学习 文章目录 表达式语句 副作用和序列点复合语句&#xff08;块&#xff09;类型转换 1.表达式 表达式由运算符和运算对象组成。下面是一些表达式&#xff1a; 4 -6 421 a*&#xff08;bc/d&#xff09;/20 q5*2 xq%3 q>3 每个表达式都有一…

软件测试零基础新手入门必看

软件测试&#xff1a;使用技术手段验证软件是否满足使用需求 目的&#xff1a;减少缺陷&#xff0c;保证质量 一、测试主流技能&#xff1a; 1.功能测试 测试主要验证程序的功能是否满足需求 2.自动化测试 使用工具或代码代替手工&#xff0c;对项目进行测试 3.接口测试 …

Golang 开发实战day02 - Print Formatting

Golang 教程02 - Print&#xff0c;Formatting Strings Go语言提供了丰富的格式化字符串功能&#xff0c;用于将数据格式化为特定格式的字符串。本课程将详细介绍Go语言中Print和Formatting Strings的用法&#xff0c;并提供代码示例供大家参考。 Print 类型及使用 1.Print …

QEMU设备直通pass through的地址映射转换

[内核:HVA]->[QEMU:HVA]的mmap地址映射 $ sudo cat /proc/2047239/maps | grep -i vfio address perms offset dev inode pathname 7f4b5444a000-7f4b5445a000 rw-s 9da50000 00:0e 13037 anon_inode:[vfi…

计算机网络 网络原理之Http

目录 1 前言2 什么是http的一次交互&#xff1f;3 理解“协议”二字4 认识URL4.1 简介4.2 URL的编码和解码(urlencode和urldecode) 5 抓包工具 fiddler6 http和https的区别7 http 头8 HTTP 状态码9 常见的 Http 服务器 1 前言 为什么要了解Http原理呢&#xff1f;因为http原理…

基于SSM SpringBoot vue个人博客网站

基于SSM SpringBoot vue个人博客网站 系统功能 首页 图片轮播 博客文章 搜索 登录注册 论坛 留言板 个人中心 我的收藏 后台管理 登录 个人中心 博客分类管理 博客文章管理 论坛管理 系统管理 管理员管理 注册用户管理 开发环境和技术 开发语言&#xff1a;Java 使用框架:…

实战经验分享:如何优化即时通讯应用的性能?

在当今移动互联网时代&#xff0c;即时通讯应用如雨后春笋般涌现&#xff0c;用户对即时通讯应用的性能和体验要求也越来越高。作为即时通讯开发领域的专家&#xff0c;我将分享一些优化即时通讯应用性能的实战经验&#xff0c;帮助开发者提升应用质量和用户满意度。 1. 优化网…

【Leetcode每日一刷】贪心算法| 45.跳跃游戏 II

1、45.跳跃游戏 II &#x1f984;解题思路&#xff1a; 这题还是比【55.跳跃游戏】难一些的。第一个版本只是说&#xff0c;求跳跃的范围&#xff0c;覆盖到了终点即可。这题则是&#xff0c;能保证覆盖范围到达终点&#xff0c;求的是最少跳几次&#xff0c;跳到终点。 这题…

289页初中级前端题助你拿下Offer,终局之战

HTML、CSS、JS三大部分都起什么作用&#xff1f; HTML内容层&#xff0c;它的作用是表示一个HTML标签在页面里是个什么角色&#xff1b;CSS样式层&#xff0c;它的作用是表示一块内容以什么样的样式&#xff08;字体、大小、颜色、宽高等&#xff09;显示&#xff1b;JS行为层…

Redis缓存【重点】

参考链接 https://xiaolincoding.com/redis/cluster/cache_problem.html#%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9 目录 缓存雪崩大量数据同时过期Redis 故障宕机 缓存击穿第一种方案&#xff0c;非法请求的限制第二种方案&#xff0c;缓存空值或者默认值第三种方案&#xff0c;使…

01、MongoDB -- 下载、安装、配置文件等配置 及 副本集配置

目录 MongoDB -- 下载、安装、配置 及 副本集配置启动命令启动 mongodb 的服务器&#xff08;单机和副本集&#xff09;启动单机模式的 mongodb 服务器启动副本集的 3 个副本节点&#xff08;mongodb 服务器&#xff09; 启动 mongodb 的客户端 MongoDB 下载MongoDB 安装1、解压…

App自动化测试笔记(一):搭建环境

一、三个环境 1、android模拟器&#xff1a;模拟安卓手机 2、androidSDK:android SDK给你提供开发测试所必须android API类库 3、java&#xff1a;android底层是c、c语言&#xff0c;应用层是java语言 二、java环境搭建 java安装 安装jdk-8u151-windows-x64.exe 配置环境变量…

JAVA的学习日记DAY1

JAVA的学习日记&#xff08;2024.3.1&#xff09;&#xff08;b站韩顺平老师课程学习笔记版&#xff09; ps:捡起忘光光的Java语言 Sublime //1. public是公有&#xff0c;class是类 //2. public class Hello表示Hello是一个类&#xff0c;是一个public公有的类 //3. Hello{…

【Redis | 第二篇】Redis的五种数据类型和相关命令

文章目录 2.Redis的数据类型和相关命令2.1常用数据类型2.2特性和用途2.2.1字符串&#xff08;String&#xff09;2.2.2哈希&#xff08;Hash&#xff09;2.2.3列表&#xff08;List&#xff09;2.2.4集合&#xff08;Set&#xff09;2.2.5有序集合&#xff08;Sorted Set&#…

SwiftUI中stroke属性的使用

在 SwiftUI 中&#xff0c;可以使用 stroke 属性来绘制形状的轮廓线。stroke 属性接受一个 Color 类型的参数&#xff0c;指定轮廓线的颜色。 以下是一个示例代码&#xff0c;演示如何在 SwiftUI 中使用 stroke 属性绘制矩形的轮廓线&#xff1a; import SwiftUIstruct Conte…

linux小记(1)

基本概念&#xff1a;不依靠扩展名来区分文件类型 好处&#xff1a;除了文本文件其他所有windows文件都无法在Linux下运行&#xff0c;包括病毒木马。 坏处&#xff1a;所有的软件都需要对linux单独开发 习惯用后缀来区分文件&#xff0c;方便管理。 -压缩包&#xff1a;*.…