qsort,头文件stdlib.h
函数原型
void qsort (void * base,size_t num,size_t size,int (*compare)(const void * a,const void * b));
base——接收待排序的任意类型的数组的首地址。
size_t——本质就是个int.
num——数组元素的个数。
size——数组每个元素的大小。
int(*compare)(const void* a,const void* a)——函数指针,指向比较函数,compare是函数指针变量
void* 类型的指针 可以接收任意类型的元素地址,让qsort可以排序任意类型数据的关键。
void* 类型的指针 不能进行解引用操作。
void* 类型的指针 不能进行加减整数的操作
函数使用
在比较函数中比较传过来的ab的值如果a的值大于b则返回正数,a == b则返回0,a小于b则返回负数,qsort根据比较函数返回的值进行排序进行排序。
int compare(const void* a,const void* b)//接收传过来的任意两个类型的元素地址
{
int *pa = (int*)a;//待排序的是个整形数组,将形式参数ab强制转换
int *pb = (int*)b;
return (*pa) - (*pb);//如果a的值比b的值大则返回正数,相等则返回0,a < b则返回负数
}
函数的返回类型只能是int
函数调用
int arr[] = {1,89,4,8,3,46,87,64,56};
int sz = sizeof(arr)/sizeof(arr[0]);
qsort(arr,sz,sizeof,compare);
使用实例
整形排序
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a,const void* b)//接收传过来的任意两个类型的元素地址
{
int *pa = (int*)a;//待排序的是个整形数组,将形式参数ab强制转换
int *pb = (int*)b;
return (*pa) - (*pb);//如果a的值比b的值大则返回正数,相等则返回0,a < b则返回负数
}
int main()
{
int arr[]= {58,9,4,6,9,4,3,7,6,4};
int sz = sizeof(arr)/sizeof(arr[0]);
qsort(arr,sz,sizeof(int),compare);//将传过来的数进行排序
int i;
for(i = 0;i < sz;i++)
{
printf("%d ",arr[i]);
}
putchar('\n');
return 0;
}
当前实现的是升序排序,假如要实现降序排序,将pa和pb互换即可。
浮点型排序
#include <stdio.h>
#include <stdlib.h>
int compare(const void* a,const void* b)
{
float* pa = (float*)a;
float* pb = (float*)b;
//return (*pa) - (*pb);两个数相减是个浮点数,要返回的是个int会导致类型冲突
if((*pa) > (*pb))
{
return 1;
}
else if((*pa) < (*pb))
{
return -1;
}
else
{
return 0;
}
}
void test1()
{
float f[] = {2.0,1.5,3.5,4.2,3.3,8.5,9.0,10.4,20.3};
int sz = sizeof(f)/sizeof(f[0]);
qsort(f,sz,sizeof(f[0]),compare);
int i;
for(i = 0;i < sz;i++)
{
printf("%f \n",f[i]);
}
}
int main()
{
test1();
return 0;
}
结构体排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stu
{
char name[20];
int age;
};
int cmp_by_age(const void* a,const void* b)
{
return ((struct stu*)a) -> age - ((struct stu*)b) -> age;//访问结构体数组中的元素ab中的年龄成员
}
int cmp_by_name(const void* a,const void*b)
{
return strcmp(((struct stu*)a)-> name,((struct stu*)b) -> name);//比较名字就是比较两个字符串
//比较三个名字的首字母的Ascll值
}
void test3()
{
struct stu s[3] = {{"zhangsan",20},{"lisi",19},{"wangwu",18}};
int sz = sizeof(s)/sizeof(s[0]);
//qsort(s,sz,sizeof(s[0]),cmp_bt_age);对结构体中的年龄成员进行排序
qsort(s,sz,sizeof(s[0]),cmp_by_name);//对姓名成员进行排序
int i;
for(i = 0;i < sz;i++)
{
printf("%s ",s[i].name);
}
putchar('\n');
}
int main()
{
test3();
return 0;
}
结构体比较是对结构体内的成员进行比较,而不是对整个结构体进行比较。