关于qsort排序字符串,比较函数中char**强制转换的理解。

本文详细介绍了qsort快速排序函数,包括其void类型的特性,参数含义,特别关注了用于字符串排序的compare函数指针。通过实例演示了如何使用qsort对字符串数组进行排序,解释了char**强制转换的原因。
摘要由CSDN通过智能技术生成

qsort相信大家都已经很熟悉了,他是一个快速排序函数,由于其形参类型为void类型,故而可以对多种数据类型进行排序,而不仅仅针对整型数据的排序,应用广泛而方便,所以掌握qsort快排可精简代码量,提高开发效率。下面我们首先看一下它的函数原型和相关参数的含义:

函数原型:void qsort(void *base,size_t num,size_t size,int(*compare)(const void*p1,const void*p2));

参数解析:

1、 qsort为函数名,而函数名前面的void,说明该函数无需返回值,仅仅作为排序使;

2、 void *base  ,表示待排序数据的其实地址(无论是排序整型还是字符串又或者是结构体类型的数据,一般都是将这些数据封装成数组来排序,所以该参数一般为数组名,ps这里有个小知识点:数组名表示该数组的地址或者数组首元素的地址);

3、 size_t num ,表示待排序数据的个数(一般为封装后的数组元素个数);

4、 size_t size ,表示待排序数据的单个数据元素的大小,也就是数组元素的大小;

5、int(*compare)(const void*p1,const void*p2), 这个参数为qsort函数的核心参数,我们来重点解析一下

    首先(*compare)表明这个参数是一个函数指针,该指针指向的函数是一个返回值为int类型,且参数为const void*p1,const void*p2 的函数;我们习惯性的将这个函数称为比较函数,通过函数指针的定义我们可以到推导出这个比较函数原型为 int compare(const void*p1,const void*p2);

   关于这个比较函数int compare(const void*p1,const void*p2),我们要特别留意它的形参类型,为两个指针!

下面我们来看一下用qsort来排序字符串的应用实例以及相关细节的解释;

头文件和主函数:

#include<stdio.h>
#include<string.h>     //由于要比较字符串的大小需调用strcmp库函数,所以需要包含这个头文件

int main()
{
   int i;
    char *p[]={"xiyangyang","meiyangyang","lanyangyang","feiyangyang"};//待排序字符串
    int sz=sizeof(p)/sizeof(p[0]);//元素个数
    qsort(p,sz,sizeof(p[0]),compare);
    for(i=0;i<sz;i++)//循环输出数组
    {
       printf("%s\n",p[i]);
    }

    return 0;
}

比较函数:
int compare(const void *p1,const void *p2) //比较函数
{

    return strcmp(*(char**)p1,*(char**)p2); //库函数比较字符串大小,按照ascII码表排序

}

回到我们的主题,为什么这里要用(char**)进行强制转换?而不是按照整型排序的(int*)那样直接使用(char*)?

首先我们看一下比较函数传过来的形参p1 p2,假设他对应字符串数组的p[0]和p[1],字符串数组的本质是一个指针数组,p[0]和p[1]分别为一个指针,各自指向一个字符串的开头,比如p[0]指向“xiyangyang”,这里可以看见p[0]可以看成一个一维字符数组的指针,那么p[0]就是这个一维数组的数组名,指向的就是这个一维字符数组的qishi地址或者首元素地址,而数字名只有在sizeof(数组名)和&数组名是才代表整个数组,所以这里如果只进行(char*)强转,比较函数内部调用的库函数就会变成这样:

             strcmp(*(char*)p1,*(char*)p2); 这里p1(假设为p[0]),p2(假设为p[1]),强转一次再解引用一次得到的只是单个字符'x'和'm',这个参数就不符合strcmp的要求了,因为strcmp()的形参也需要为2个指针!而使用char**就可以解决这个问题,首先char*将指针强转为字符指针类型,再加一个*保证他是一个二级指针(字符串数组就相当于是一个二级数组),这样解引用一次后p1,p2仍然为指针,这样就符合strcmp的参数要求了;

下面是排序后的运行结果。

feiyangyang
lanyangyang
meiyangyang
xiyangyang

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值