qsort库函数实现原理

首先要知道是qsort库函数的使用方法,使用时要添加头文件#include<stdlib.h>
其次qsort需要传参且要传四个参数
传参模板qsort(void*base,size_t num,size_t size,int(*compar)(const void*,const void*))【size_t是无符号整型】
各位参数的意思
1.void*base是指针,指向的是待排序的数组(待排序必须为一个数组)的第一个元素(插入小知识:void* 不可以解引用需要强制类型转换才可以解引用(缺点),void*代指任何类型的指针解决了不知道指向哪种类型指针的问题(优点))
2.是base指向的待排数组元素的个数
3.base指向的待排数组元素的大小
4.指向的就是两个元素的比较函数
       了解以上qsort知识点后我们用代码来实现qsort的使用,进而加深对qsort库函数的理解。

首先来实现对整型数组的排序:
首先我们来实现函数主体

int main()
{
	int arr[] = {1,4,5,6,8,3,22,48,15};
	int lenth = sizeof(arr) / sizeof(arr[0]);//数组的长度
	int size = sizeof(arr[0]);//数组里单个元素的大小,占几个字节
	qsort(arr, lenth, size, com_int_up);
   // com_int_up为整型比较函数的地址,up代表升序,接下来会讲原理
	for (int i = 0; i < lenth; i++)
		printf("%d ", arr[i]);
 return 0;
}

然后再实现比较函数:

小编叮嘱:

如果比较函数放在int main 之前就不需要函数声明了,如果放在int main之后则要声明(不要忘记了哦)

int com_int_up(const void* p1, const void* p2)
{
  //void* 不可以解引用需要强制类型转换才可以解引用为其他指针
	return  *(int*)p1 - *(int*)p2;//因为是对整型排序,所以需要将p1强制类型转换为(int *)
//不要忘记对转换后的指针进行解引用,只有当解引用后才能访问到p1所指的内容哦
}

让小编详细讲一下为什么上面这个比较函数是升序的。

因为当*(int*)p1大于*(int*)p2时会返回一个大于1的数

           *(int*)p1小于*(int*)p2时会返回一个小于1的数

            *(int*)p1等于*(int*)p2时会返回1

当sqort接收到了一个大于1的数会交换两个数的位置,所以当*(int*)p1大于*(int*)p2时交换p1与p2的位置就会变为升序排列。如果在比较函数中return *(int*)p2-*(int*)p1;则会是降序排列。

接下来小编带大家来实现对字符数组的排序:

步骤与实现整型数组排序类似,首先第一步也是实现函数主体(小编猜想各位友友对这里都理解了,小编就偷偷懒不详细讲解了)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char ch[] = "adgrkfngh";
int lenth = sizeof(ch) / sizeof(ch[0]);
int size = sizeof(ch[0]);
 qsort(ch, lenth, size, com_char_up);
for (int i = 0; i < lenth; i++)
	printf("%c ", ch[i]);
return 0;
}

然后再实现比较函数:

这里就与整型的比较不相同了

int com_char_up(const void* p1, const void* p2)
{
	return 	strcmp((char*)p1, (char*)p2);//字符的比较用strcmp函数
}

小编担心有些友友会依葫芦画瓢对(char*)p1再次解引用,小编要说对于字符和字符串要访问其中的内容都不需要解引用,我们只需要知道指向它们的指针就可以。

最后是对结构体数组里成员的比较

首 先还是需要实现函数主体和定义结构体

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu
{
	char name[20];
	int age;
};
int main()
{	 
  struct stu s[] = { {"zhangsan",18},{"lisi",14},{"wangwu",17} };//对字符串初始化要加"",不要忘记啦!!!
	   lenth = sizeof(s) / sizeof(s[0]);
	   size = sizeof(s[0]);
	   qsort(s, lenth, size, com_str_name_up);//对结构体成员name进行比较
	   for (int i = 0; i < lenth; i++)
		   printf("%s ", s[i].name);//这里也可以是(s+i)->name
	   printf("\n");//打印完所有结构体成员name后换行                                                 
     qsort(s, lenth, size, com_str_age_up);//对结构体成员name进行比较
	   for (int i = 0; i < lenth; i++)
		   printf("%d ", s[i].age);  
	 return 0;
}

接下来要实现对结构体成员的比较函数

int com_str_name_up(const void* p1, const void* p2)
{
	return 	strcmp(((struct stu*)p1)->name ,((struct stu*)p2)->name);
//首先将p1强制类型转换为指向结构体的指针(struct stu*)【因为结构体的类型是struct stu】
//结构体可以直接->指向结构体成员的内容
}
int com_str_age_up(const void* p1, const void* p2)
{
	return 	((struct stu*)p1)->age 
}

以上就是小编对qsort库函数的理解,感谢各位友友的支持!!! 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值