个人主页:
仍有未知等待探索_数据结构,小项目,C语言疑难-CSDN博客
专题分栏:
C语言疑难_仍有未知等待探索的博客-CSDN博客
目录
一、引言
二、讲解实现
1、给整型数组排序
排序实现
总代码
2、qsort中参数cmp函数怎么实现
1.浮点型
2.结构体类型
一、引言
1、第一个参数是void*base:指向要排序的数组的第一个对象的指针,转换为 void*。
2、第二个参数是size_t num:数组中按基数指向的元素数。size_t是无符号整数类型。
3、第三个参数是size_t size:数组中每个元素的大小(以字节为单位)size_t是无符号整数类型。
4、第四个参数是int (*compar)(const void*p1,const void*p2)):指向比较两个元素的函数的指针。
大家是不是很疑惑,咱们写冒泡排序或者选择排序的时候,感觉也没有那么的复杂,为什么C语言库函数中qsort函数的参数那么的麻烦。为什么还要传size_t size呢?大家是不是会有这样的疑问呢?今天我就给大家详细的讲解一下!(库函数中qsort函数是快速排序,我用冒泡排序实现)
二、讲解实现
1、给整型数组排序
首先,我们需要先把自定义函数的参数给设计好,但是因为我们是实现库函数中的qsort函数,所有我们就直接把库函数中的参数写出来就行了。
我们现在要排序的是整型数组,所以也需要一个整型数组。
sz是为了计算出数组的长度。
问:为什么自定义函数的接收数组的参数类型是void*,而不是int*呢?
答:void* 是一种无类型指针,可以指向任意类型的数据,无需强制类型转换。意思就是说,当你把数组arr传给void*base的时候,不用管为什么base的类型不是int*,可以把void*类型理解为一个万能的类型。(注意:void*类型的变量,不能直接进行解引用访问,也不能进行指针运算,想进行上述操作必须进行强制类型转化)
#include<stdio.h>
int cmp(void* x, void* y)
{
return *(int*)x - *(int*)y;
}
//声明自定义排序函数
void qsort_m(void* base, size_t num, size_t size,int (*compar)(const void* p1, const void* p2));
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };//提供一个整型数组
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组的长度
qsort_m(arr, sz, sizeof(arr[0]), cmp);//自定义排序函数的调用
int i = 0;
for (i = 0; i < sz; i++)//输出
printf("%d ", arr[i]);
return 0;
}
排序实现
void qsort_m(void* base, size_t num, size_t size, int (*compar)(const void* p1, const void* p2)) { int i = 0, j = 0; for (int i = 0; i < num - 1; i++) { for (int j = 0; j < num - 1 - i; j++) { if (compar(((char*)base + j * size), (char*)base + (j + 1) * size) > 0) { //交换 swap((char*)base + j * size, (char*)base + (j + 1) * size,size); } } } }
compar(((char*)base + j * size), (char*)base + (j + 1) * size),这块要把base强转为char*类型,目的是这个char*能表示更多的数据类型,char*解引用仅能得到一个字节的数据,而int*等其他的类型解引用之后,能得到更多的字节的数据均比char*的大,所以用char*类型可以得到所有传进来的数据,所以,到这里就明白了,为什么要传入数据类型的大小,j*size是为了让数组访问下一个空间的数据。
最后就剩一个比较简单的交换函数。
void swap(char* buf1, char* buf2, size_t size)
{
int i = 0;
for (int i = 0; i < size; i++)
{
int tmp;
tmp = *(buf1 + i);
*(buf1 + i) = *(buf2 + i);
*(buf2 + i) = tmp;
}
}
总代码
#include<stdio.h>
int cmp(void* x, void* y)
{
return *(int*)x - *(int*)y;
}
void swap(char* buf1, char* buf2, size_t size);
void qsort_m(void* base, size_t num, size_t size, int (*compar)(const void* p1, const void* p2));
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1 };//提供一个整型数组
int sz = sizeof(arr) / sizeof(arr[0]);//计算数组的长度
qsort_m(arr, sz, sizeof(arr[0]), cmp);//自定义排序函数的调用
int i = 0;
for (i = 0; i < sz; i++)//输出
printf("%d ", arr[i]);
return 0;
}
void qsort_m(void* base, size_t num, size_t size, int (*compar)(const void* p1, const void* p2))
{
int i = 0, j = 0;
for (int i = 0; i < num - 1; i++)
{
for (int j = 0; j < num - 1 - i; j++)
{
if (compar(((char*)base + j * size), (char*)base + (j + 1) * size) > 0)
{
//交换
swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
}
}
}
}
void swap(char* buf1, char* buf2, size_t size)
{
int i = 0;
for (int i = 0; i < size; i++)
{
int tmp;
tmp = *(buf1 + i);
*(buf1 + i) = *(buf2 + i);
*(buf2 + i) = tmp;
}
}
2、qsort中参数cmp函数怎么实现
cmp是一个函数指针,这个函数指针指向的是一个函数,这个函数的返回值是int类型的。当返回值<0 ,p1 指向的元素先于 p2 指向的元素 ;返回值=0 ,p1 指向的元素等效于 p2 指向的元素;返回值 >0 ,p1 指向的元素在 p2 指向的元素之后。
如果想详细的知道的话,请点链接,看我上一篇。
C语言qsort函数的使用_仍有未知等待探索的博客-CSDN博客文章来源:https://www.toymoban.com/news/detail-725410.html
1.浮点型
int cmp(const void* p1, const void* p2)
{
return *(float*)p1 - *(float*)p2;
}
2.结构体类型
typedef struct Stu
{
char name[20];
int score;
}Stu;
int cmp(const void* p1, const void* p2)
{
return ((Stu*)p1)->score - ((Stu*)p2)->score;
}
int main()
{
Stu s[3] = { { "张三",50 }, { "王五",70 }, { "李四",60 } };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp);
for (int i = 0; i < sz; i++)
printf("%s %d\n", s[i].name,s[i].score);
return 0;
}
最后、谢谢大家的支持 !文章来源地址https://www.toymoban.com/news/detail-725410.html
到了这里,关于C/C++qsort函数的实现(冒泡排序)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!