因为总是忘记有qsort这个函数,导致遇到需要排序的题的时候,总是要写着类似的代码,所以特此单独把qsort拿出来单独整理一遍,让自己能够熟练掌握,也以免之后忘记了qsort可以拿自己的文章看。

目录

一、论冒泡排序和qsort

1、qsort 是什么?

2、qsort在程序中使用

1.关于cmp函数的一些规定

2、介绍一个指针类型 void*类型

3、模拟qsort

二、回调函数

三、在最后



一、论冒泡排序和qsort

       冒泡排序的核心思想:相邻元素两两比较

  写一个冒泡排序函数:


#include<stdio.h>void bubble_sort(int arr[], int sz);//函数声明int  main()
{//先创建一个数组int arr[] = { 4,8,9,3,5,2,1,7 };//通过sizeof求元素个数int sz = sizeof(arr) / sizeof(arr[0]);//把数组排成升序bubble_sort(arr, sz);//打印数组内容int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}//这个函数只能排整型数组
void bubble_sort(int arr[], int sz)
{int i = 0;while (sz){int flag = 0;for (i = 0; i < sz - 1; i++){if (arr[i] > arr[i + 1])//元素两两比较{int tmp = arr[i];arr[i] = arr[i + 1];arr[i + 1] = tmp;flag = 1;}}sz--;if (flag == 0){break;//如果数组内容一开始就是按规则有序排列的,可以进行判断优化}}
}

请注意:这样的冒泡排序有一个弊端只能排序整型数据,因为在最开始函数定义的时候已经把参数写死了。

下面开始介绍一个库函数qsort


1、qsort 是什么?

  qsort是一个使用快速排序的思想实现的一个排序函数。

  并且qsort 可以排序任意类型的数据。

下面是关于qsort函数参数的介绍:


void qsort(void* base, size_t num, size_t size,int (*cmp)(const void* e1, const void* e2));
//
//void* base 你要排序的数据的起始位置
//size_t num 待排序的数据元素的个数
//size_t size 待排序的数据元素的大小(单位是字节)
//int (*cmp)(const void* e1, const void* e2)) //函数指针-比较函数 cmp就是一个比较函数的地址,也就是这个比较函数的函数指针//e1指向了你要比较的第一个元素  e2指向了你要比较的第二个元素//e1 e2 是你要比较的两个元素的地址

2、qsort在程序中使用

   写一个程序使用一下:


#include<stdio.h>
#include<stdlib.h>int cmp_int(const void* e1, const void* e2);int  main()
{//先创建一个数组int arr[] = { 4,8,9,3,5,2,1,7 };//通过sizeof求元素个数int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_int);//打印数组内容int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}//比较两个整型元素
//这样排序默认是升序排列
//
int cmp_int (const void*e1,const void*e2)
{   return (* (int*)e1 - *(int*)e2);//所以比较的时候要强制类型转换一下
}

1.关于cmp函数的一些规定

注意其对于函数参数所传递的void*指针的解应用需要进行强制类型转换,比较什么类型的数据,就强制类型转换成什么类型,随后进行比较。

       注意返回值规定
               //e1指向的元素 > e2指向的元素 返回值 >0
               //e1指向的元素 = e2指向的元素 返回值 =0
               //e1指向的元素 < e2指向的元素 返回值 <0

  默认这样传递返回值,是升序排列。

//这样排序默认是升序排列
//
int cmp_int (const void*e1,const void*e2)
{   return (* (int*)e1 - *(int*)e2);//所以比较的时候要强制类型转换一下
}
//注意规定://e1指向的元素 > e2指向的元素 返回值 >0//e1指向的元素 = e2指向的元素 返回值 =0//e1指向的元素 < e2指向的元素 返回值 <0

  如果想要变成降序排列

  可以改变e1 e2相减位置,或者直接整体加负号使其逻辑相反即可。

//如果想改成降序排列
//可以改变e1 e2相减位置,或者直接整体加负号使其逻辑相反即可int cmp_int(const void* e1, const void* e2)
{return -(*(int*)e1 - *(int*)e2);
}

插入一个知识点:


2、介绍一个指针类型 void*类型

  论void*的包容性:

void*的指针是无具体类型的指针,可以接受任意类型的地址。是不能直接进行解应用操作的,也不能进行+ -整数的操作。

注意在使用指针指向的内容的时候,要对其强制类型转换再解引用。


3、模拟qsort

  注意在my_qsrt中向cmp传参时的强制类型转换:

    在这里传参比较的时候不能直接传递void*类型的 arr,void*类型的数据不能加减操作。

    将void*类型强制转换成最小类型char*类型,后续根据len进行步长的加减。

    根据cmp返回参数规定,以及qsort默认排列升序,所以是 >0。

//模拟qsort#include<stdio.h>void my_qsort(void* arr, int sz, int len, int cmp(void* e1, void* e2));
int cmp_int(const void* e1, const void* e2);int main()
{int arr[] = { 1,2,5,4,7,8,6,3,9 };int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, sz, sizeof(arr[0]), cmp_int);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return;
}int cmp_int (const void*e1,const void*e2)
{   return (* (int*)e1 - *(int*)e2);
}void my_qsort(void* arr, int sz, int len, int cmp(const void* e1, const void* e2))
{int i = 0;while (sz){int flag = 0;for (i = 0; i < sz - 1; i++){//注意这里传参比较的时候不能直接传递arr,void*类型的数据不能加减操作//将void*类型强制转换成最小类型char*类型,后续根据len进行步长的加减//根据cmp返回参数规定,以及qsort默认排列升序,所以是 >0if (cmp((char*)arr + len * i, (char*)arr + len * (i + 1) )> 0){int tmp = *((char*)arr + len * i);*((char*)arr + len * i) = *((char*)arr + len * (i + 1));*((char*)arr + len * (i + 1)) = tmp;flag = 1;}}sz--;if (flag == 0){break;}}
}

二、回调函数

       回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个 函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

        !注意:回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。(就比如在使用qsort函数的时候调用的cmp函数


三、在最后

第一次写完一个正式的关于知识点的博客,vpurple表示自己很开心哈哈哈,这次费的时间还挺长的,还是对这个编辑器运用不熟练www,不过在写这个博客的时候又重新复习了一遍,真的希望要把它记在心里呜呜呜

反思一下其实我对于c语言后半部分的知识点基本功都不太扎实,还是要趁着暑假期间把它们全都顺一遍,坚持日更!!!flag反正是立在这里了www绝对不会打脸的!!!

还有在最后祝我早日对于qsort函数使用烂熟于心,还有void*和回调函数这些知识点,全都记住!!!

qsort — c语言中自带的排序函数(附带void*、回调函数知识点相关推荐

  1. C语言中对结构体排序

    在C语言中对结构体排序 用qsort()函数进行排序, qsort()里面要传入4个参数–qsort(数组名,数组长度,sizeof(),排序方法) 实验9-5 查找书籍 (20分) 给定n本书的名称 ...

  2. C语言中的带参宏和带参函数的区别

    C语言中的带参宏和带参函数的区别 (1) 带参函数中的形参是变量,因此有类型检查.而带参宏只是简单的字符串替换. (2) 从程序执行的过程来看,带参宏是在预处理阶段被预处理器处理的.而带参函数是在程序 ...

  3. C语言中的几种排序算法

    C语言中的几种排序算法 在编程练习时,我们经常会遇到一些将一串乱序的数字排列成有序的数列(递增,递减)的问题,以此起到解决问题的效果.目前我使用的比较熟练的有三种排序算法,冒泡排序法,快速排序法,另外 ...

  4. 用c语言对文件的写入和保存,C++_C语言中对文件最基本的读取和写入函数,C语言read()函数:读文件函数( - phpStudy...

    C语言中对文件最基本的读取和写入函数 C语言read()函数:读文件函数(由已打开的文件读取数据)头文件: #include 定义函数: ssize_t read(int fd, void * buf ...

  5. c语言把一个字符从指定文件中读取的函数,C语言中对文件最基本的读取和写入函数...

    C语言中对文件最基本的读取和写入函数 C语言read()函数:读文件函数(由已打开的文件读取数据)头文件: #include 定义函数: ssize_t read(int fd, void * buf ...

  6. 【C/C 】浅谈C/C 中函数指针与回调函数

    01.函数指针 1.1.函数指针定义 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似.我们可以把函数的这个首地址(或称入口地址)赋予 ...

  7. 【C语言进阶深度学习记录】三十二 函数指针与使用函数指针实现回调函数

    回调函数是非常重要的概念 文章目录 1 函数的类型 2 函数指针 2.1 函数指针的使用 2.2 使用函数指针实现回调函数 3 总结 1 函数的类型 跟以前学数组的时候是一样的,C语言中的数组是有自己 ...

  8. typedef函数指针_C语言函数指针之回调函数

    1 什么是回调函数? 首先什么是"回调"呢? 我的理解是:把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调. 如果代码立即被执行就称为同 ...

  9. c语言函数指针封装函数,C语言之函数指针、回调函数的使用

    一.背景 首先看下如下代码,这个定义是放在头文件的,在程序中tCdrvCallbackFkt也定义了另一个变量,而且括号后面还跟定义了几个变量,不理解这个定义. typedef void (PUBLI ...

最新文章

  1. 在使用Reference Source调试.Net 源代码时如何取消optimizations(代码优化)-翻译
  2. ICCV 2021审稿结果出炉,这里有一份Rebuttal写作指南
  3. HLS实现点播和直播时,M3U8文件的不同
  4. 打印helloworld,注释,从源文件到可执行文件
  5. SCSS 实用知识汇总
  6. Hibernate Collection Cache如何工作
  7. 1069. 微博转发抽奖(20)
  8. php怎样传数据到html代码,传递数据到PHP文件与HTML模板
  9. WordPress程序备受喜爱的原因:十八般武艺(3)
  10. 作业6--四则运算APP之Sprint计划
  11. php留言板翻页,php翻页函数 - 沐攸的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  12. python将对象放入列表根据某个属性排序_关于python:如何根据对象的属性对对象列表进行排序?...
  13. GTK+ 3.5.18 发布,GUI 开发工具包
  14. c语言实现通讯录_C语言实现双人猜数字游戏
  15. 最简单的基于FFmpeg的移动端例子:Android 视频解码器-单个库版
  16. 数据结构--数组+链表实现哈希表
  17. 【数字信号去噪】基于matlab小波软阈值+硬阈值+改进阈值数字信号去噪【含Matlab源码 1025期】
  18. 研发团队管理--向上沟通
  19. 苹果股价盘后涨超5% 市值一度突破万亿
  20. 3dsmax 制作u型长方体

热门文章

  1. 易语言读取Mysql表数据
  2. 在线UTF16编码/解码
  3. TP5框架Redis的使用
  4. node版本管理n的使用
  5. Java转Go:java开发者转学go语言,请给我一些建议和学习推荐
  6. 常见范数(向量范数、矩阵范数)及其在机器学习算法的应用
  7. 云栖大会分享:买单侠的数据库架构之路
  8. 2021年教师资格证面试试讲稿:小学音乐《放马山歌》
  9. ubuntu18.04安装fcitx输入法
  10. Java中如何通过键盘输入一个数组以及创建方式