手把手教你使用qsort函数

简介: 手把手教你使用qsort函数

一、qsort函数

1.qsort函数的用途

qsort的作用是对不同数据类型的数组的内容进行排序,排序的升序降序可以由你所提供的函数参数所改变。

2.qsort函数的参数

图片出自:cplusplus.com - The C++ Resources Network

从函数的参数部分我们可以看出,qsort一共有4个参数

第一个是无类型的指针拓展:可忽略(为什么是无类型的呢?因为qsort函数不知道传递过来的是什么类型的数组,它不知道我们要对什么样的数组排序,它得通过这种方式先将地址传递到函数中,再在函数中判断这一类型指针的权限,如此便可顺利地实现地址的查询,这才能按要求进行排序,毕竟不同类型的指针,所对应的权限不一样,比方说int*和char*类型的,这两个类型的指针加1一个跳过4个字节,另一个加1跳过1个字节)在使用qsort函数时要传递的是被排序数组的首地址


第二、三个是无符号整型(size_t)我们使用sizeof()函数得到的整数便是size_t类型的,它和整型相似。在使用qsort函数时可以传递整型数据,大于0即可,没有什么数组的元素个数和元素大小是小于等于0的吧?要传递的分别是数组的元素个数和数组一个元素的大小


第四个参数通俗点来说就是一个函数,这个函数的返回值是int型 在观察两个参数前我们先不看const,那么两个参数是无类型(原因与之前一致)指针,再加上const,将地址对应的数值常量化,使其不能被修改,这一步是为了提高代码的安全性,毕竟我们只是排序,是不会对数组中的内容进行修改的。在使用qsort时我们要传递过去的时一个能够对比两个指针对应数据大小的函数,第一个参数大于第二个参数,返回大于0的数,小于返回小于0的数,等于返回0,这样使用qsort便会升序排序,你也可以反过来,第一个参数大于第二个参数,返回小于0的数......如此便会降序排序

二、使用qsort函数

1.如何使用

我们先随便来一个数组

int arr1[10] = { 1,3,2,4,7,6,5,8,10,9 };

我们接下来的目标就是对它进行排序,先排成升序

接着求出元素个数,和一个元素对应的大小

1. int sz1_num = sizeof(arr1)/sizeof(arr1[0]);
2. int sz1=sizeof(arr1[0]);

接下来便是比大小函数

int cmp_int(void const*i1,void const*i2)
{
  return *((int*)i1) - (*(int*)i2);
}

一步步分析,首先是函数返回值类型和参数,这两个得和qsort所定义的一致   再然后,根据自己要排序的数组类型,将数据强制类型转换为对应类型的数据   这里我们要排序的类型是int型的数组,我们先强转即(int*)i1,接着对强转后的数据解引用,如此就可以使用该地址对应的整型类型的数据   i2同理取出,用做差的方式比大小,不难看出,第一个数据对应的值大于第二个数据对应的值返回大于0的数,小于,返回小于0的数,等于返回0,跟我们之前的要求一致。


如此便可使用qsort函数了,所有的要素都集齐了。为了能够看出排序的效果,这里笔者写了一个专门打印整型类型数组的函数

void print_int(int*i1, int sz)
{
  int i = 0;
  for (;i<sz;i++)
  {
    printf("%d ", *(i1 + i));
  }
  printf("\n");
}

2.代码实现

int cmp_int(void const*i1,void const*i2)//比大小
{
  return *((int*)i1) - (*(int*)i2);
}
void print_int(int*i1, int sz)//打印
{
  int i = 0;
  for (;i<sz;i++)
  {
    printf("%d ", *(i1 + i));
  }
  printf("\n");
}
int main()
{
  int arr1[10] = { 1,3,2,4,7,6,5,8,10,9 };//被排序数组
  int sz1_number = sizeof(arr1)/sizeof(arr1[0]);//数组元素个数
  int sz1 = sizeof(arr1[0]);//数组单个元素大小
  print_int(arr1, sz1_number);//打印排序前
  qsort(arr1, sz1_number,sz1, cmp_int);//使用qsort进行排序
  print_int(arr1, sz1_number);//打印排序后
}

运行结果如下:

3.小结:

数组首元素地址,数组元素个数,数组单个元素大小,比大小函数,这四个要素凑齐便可进行快速排序,可能现在你觉得复杂,但慢慢的你就会熟练,这是一个很好用的函数,别放弃它。

4.拓展

用所学知识看懂如下代码,并尝试自己写下

#include<stdio.h>
struct monster//创建结构体类型
{
  char name;
  int power;
  int life;
}typedef mon;//将struct monster这个结构体类型定义一个新名字
int cmp_mon_life(void const* m1, void const* m2)//比大小
{
  return  ((mon*)m2)->life - ((mon*)m1)->life;
}
void print_cmp_life(mon* i1, int sz)//打印
{
  int i = 0;
  for (; i < sz; i++)
  {
    printf("%d ", (i1 + i)->life);
  }
  printf("\n");
}
int main()
{
  mon arr2[3] = { {"goblin",10,100} ,{"wolf",15,80} ,{"human",12,150} };
  int sz2_number = sizeof(arr2) / sizeof(arr2[0]);//数组元素个数
  int sz2 = sizeof(arr2[0]);//数组单个元素大小
  print_cmp_life(arr2, sz2_number);//打印排序前
  qsort(arr2, sz2_number,sz2, cmp_mon_life);//排序
  print_cmp_life(arr2, sz2_number);//打印排序后
}

今天的分享到这里就结束了,感谢各位友友的来访,祝各位友友前程似锦O(∩_∩)O

相关文章
|
8月前
|
C语言
【C语言】拿捏冒泡排序(图解)
【C语言】拿捏冒泡排序(图解)
|
7月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
8月前
|
存储 搜索推荐 算法
C语言数据结构算法,常用10种排序实战
插入排序(Insertion Sort) 希尔排序(Shell Sort) 选择排序(Selection Sort) 冒泡排序(Bubble Sort) 归并排序(Merge Sort) 快速排序(Quick Sort) 堆排序(Heap Sort) 基数排序(Radix Sort)
85 1
C语言数据结构算法,常用10种排序实战
|
8月前
|
存储 C语言
C语言进阶之冒泡排序
C语言进阶之冒泡排序
62 0
|
8月前
|
存储 C语言
【C语言进阶篇】 数组常考笔试题万字解析(下)
【C语言进阶篇】 数组常考笔试题万字解析(下)
44 0
|
人工智能 搜索推荐
【数据结构】深入浅出讲解计数排序【图文详解,搞懂计数排序这一篇就够了】
【数据结构】深入浅出讲解计数排序【图文详解,搞懂计数排序这一篇就够了】
80 0
|
C语言
【C语言进阶篇】 你真的学会数组了嘛?数组笔试题万字解析(上)
【C语言进阶篇】 你真的学会数组了嘛?数组笔试题万字解析(上)
179 0
【C语言进阶篇】 你真的学会数组了嘛?数组笔试题万字解析(上)
|
算法 搜索推荐 C语言
进阶C语言:冒泡排序
初阶C语言--冒泡排序、qsort函数的使用、使用冒泡排序的思想实现类似于qsort的函数。
697 3
|
算法 Java 测试技术
二分查找算法简单进阶
这里将对刷题笔记一文末提及的几道推荐二分法进阶题目进行说明介绍。一道简单题加了一定的文字修饰,一道中等题巧用二分查找,以下为刷题笔记一链接,题目链接在文末提供。
164 0
|
存储 C语言
初阶C语言 第三章-------《数组》(一维数组,二维数组,数组越界.....) 知识点+思维导图+基本练习题+超详细+通俗易懂(建议收藏)
初阶C语言 第三章-------《数组》(一维数组,二维数组,数组越界.....) 知识点+思维导图+基本练习题+超详细+通俗易懂(建议收藏)