函数原型
void qsort(void *base, size_t num, size_t width,int(*compare)(const void*,const void*));
参数:base 指向排序数组的起始地址
num 数组元素个数
width 每个元素所占字节数
compare 指向比较函数的指针
重点是compare比较函数,原型是
int compare(const void *p1, const void *p2)
当返回值小于0 ,p1指向元素被排在p2指向元素左边。即[*p1, *p2];
当返回值大于0 ,p1指向元素被排在p2指向元素右边。即[*p2, *p1];
当返回值等于0 ,p1指向元素和p2指向元素顺序不确定。
函数怎么写?只需要记住返回值类型只要包含负数和正数的类型都可以,比如int,char。然后参数是2个需要用来排序的元素的地址即可。
比如需要升序排序char类型数组可以这样写:
int char_cmp(const char *param1, const char *param2)
{
if( *param1 < *param2)
{
return -1;
}
else if ( *param1 > *param2)
{
return 1;
}
else
{
return 0;
}
}
或者这样
char char_cmp(char *param1, char *param2)
{
if( *param1 < *param2)
{
return -1;
}
else if ( *param1 > *param2)
{
return 1;
}
else
{
return 0;
}
}
调用qsort函数的时候再将函数经过函数类型的强制转换,转换成compare指针指向的类型(int(*)(const void*, const void *))再传参即可,比如包含10个char类型数据的数组array的排序:
qsort(array, 10, 1, (int(*)(const void*,const void*))char_cmp);
结构体数组元素1,2级排序:
有array结构体数组如下
typedef struct
{
unsigned char data1;
int data2;
} compare_data_t;
compare_data_t array[10];
比较函数为:
int struct_cmp(compare_data_t *param1, compare_data_t *param2)
{
if (param1->data1 < param2->data1)
{
return -1;
}
else if (param1->data1 > param2->data1)
{
return 1;
}
else
{
if (param1->data2 < param2->data2)
{
return -1;
}
else if (param1->data2 > param2->data2)
{
return 1;
}
else
{
return 0;
}
}
}
函数调用同样为:
qsort(array, 10, sizeof(array)/sizeof(array[0]), (int(*)(const void*,const void*))struct_cmp);
qsort函数调用的时候再强制转换compare参数的类型好处在于:
用户可时刻关注compare函数的实现而不必过多的关注函数体内各个参数类型的强制转换问题,只需要函数调用的时候再一次性进行函数类型的强制转换,可读性更强。