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语言数据类型讲解详细说明

C语言数据类型 C语言中的数据类型可以分为几大类&#xff1a;基本数据类型、非基本数据类型和复合数据类型。接下来&#xff0c;我们将逐一进行详细和生动的讲解&#xff0c;并通过实例代码来辅助理解。 基本数据类型 基本数据类型是C语言中最基本、最原始的数据类型。它们包…

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基本数据类型 程序是由算法…

个性化服务的未来:基于API的电商平台数据定制和推荐系统

随着电商行业的快速发展&#xff0c;个性化服务已经成为提升用户体验和增加用户粘性的关键。基于API的电商平台数据定制和推荐系统是实现这一目标的重要技术手段。 未来&#xff0c;个性化服务可能会朝以下几个方向发展&#xff1a; 更精准的用户画像&#xff1a;通过API接口…

C语言中的结构体和c++中的类,有什么区别、作用、联系、优缺点

C语言中的结构体&#xff08;Struct&#xff09;与C中的类&#xff08;Class&#xff09; 区别 基本组成&#xff1a; C语言的结构体&#xff1a;只包含数据成员&#xff0c;不包含成员函数。结构体主要用于封装多个不同类型的数据。C的类&#xff1a;包含数据成员和成员函数。…

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 每个表达式都有一…

click house 数据库的intDiv函数计算原理

select intDiv(500000,50); --10000 select intDiv(500001,50); --10000 select intDiv(500050,50); --10001 Java代码实现 public static int intDiv(int a, int b) {if (b ! 0) {return a / b;} else {throw new ArithmeticException("Division by zero is not allowe…

Java学习笔记003——类成员的访问修饰符

在Java语言中&#xff0c;类成员的访问修饰符用于定义类成员的可见性&#xff0c;即哪些其他类可以访问这些成员。类成员包括字段&#xff08;变量&#xff09;、方法和构造器。Java提供了四种访问修饰符来控制成员的访问权限&#xff1a; public&#xff1a;公共的。任何类都可…

摘要, 加密, 数字签名, 数字证书以及加密通信简要介绍

如今 HTTPS 已几乎完全取代 HTTP, 大部分的网络通信也都有使用加密层, 那么对于非对称加密以及数字证书的学习也就不可避免了. 摘要 摘要是一个很简单的概念, 可以类比人类的指纹. 摘要是由数据计算而来的, 当数据变更的时候, 它的摘要也随之变更. 对比现实就是, 只要是不同的…

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

软件测试&#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…

C++中的静态成员变量和静态成员函数

一、静态成员变量 静态成员变量使用static修饰的成员变量。静态成员变量不属于某一个对象&#xff0c;而是属于整个类&#xff0c;因此静态成员变量不能设置缺省值&#xff0c;因为缺省值是给予初始化列表用于初始化对象的。 静态成员变量需要再类内声明&#xff0c;类外定义…

计算机网络 网络原理之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原理…

前端知识学习之proxy代理对象

前端proxy代理对象 1.学习背景 学习vue3过程中&#xff0c;发现vue3相比于vue2的最大优势在于&#xff0c;尤雨溪大佬在vue3中使用proxy 代理对象&#xff0c;vue2中使用的双向绑定Object.defineProperty&#xff0c;这两者有什么区别 2.Object.defineProperty 使用方法&am…

ECMAScript语法

什么是ECMAScript ECMAScript 是一种由 ECMA国际&#xff08;前身为欧洲计算机制造商协会&#xff09;通过 ECMA-262 标准化的脚本程序设计语言。 ECMAScript 是一种可以在宿主环境中执行计算并能操作可计算对象的基于对象的程序设计语言。ECMAScript 最先被设计成一种 Web 脚…

java使用mapper操作mysql

上半部分搭建springboot 简单使用数据库查询 添加链接描述 在impl接口实现操作 如 package com.service.impl; import com.dao.UserMapper; import com.pojo.User; import com.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import…

基于SSM SpringBoot vue个人博客网站

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