C 语言中的 qsort 排序函数
C 语言中的 qsort 函数是一个功能强大的标准库函数,调用它需要包含头文件 <stdlib.h>。
正如它的函数名一样,它的作用是进行排序,而由于在函数内部采用快速排序算法(quick sort),所以它被命名为”qsort”。
该函数的声明是:1
void qsort(void *base, size_t num, size_t size, int (*compare)(const void *, const void *));
- base:通用指针类型,表示要排序的数组,可以是任意类型数组。
- num:数组中的元素数量,也就是待排序的 base 数组的长度。
- size:base 数组中每个元素的大小,通常使用 sizeof 运算符得到。
- compare:函数指针类型,表示该函数需要传入一个 返回值类型是 int,形参列表是
const void *, const void *
的表示比较规则的函数。
比较规则和 compare 函数指针
1 | int compare(const void *a, const void *b); |
qsort 函数只会进行 升序排序,compare 函数就是用来判断两个元素的大小关系的。
- 返回值等于 0,则 a == b.
- 返回值大于 0,则 a > b.
- 返回值小于 0,则 a < b.
如果我们想升序排序,只需要 a 小于 b 的时候返回负数,a 大于 b 的时候返回正数,a 等于 b 的时候返回零。
降序排序的逻辑和升序相反。当 a 实际上小于 b 的时候返回正数,那么 qsort 就会认为 a 逻辑上大于 b,而 qsort 函数只会进行升序排序,所以 a 作为实际上小的数字,但是因为 a 逻辑上大,所以 a 会排在后面,这就相当于降序排序。
排序基本数据类型的数组
以 int 为例1
2
3
4
5
6int my_cmp(const void *a, const void *b){
// 将 a 和 b 转换成 int* 类型,然后才可以进行比较操作
const int *num1 = a;
const int *num2 = (const int*)b; // 对于 C 语言而言,强转语法可写可不写
// 后续表示大小规则的逻辑
}
排序自定义结构体数组
假设有一个自定义类型 Student1
2
3
4
5
6
7
8
9
10
11
12typedef struct{
int stu_id;
char name[25];
int age;
}Student, Students[1024];
int my_cmp(const void *a, const void *b){
// 将 a 和 b 转换成 Student* 类型,然后才可以进行比较操作
const Student *s1 = a;
const Student *s2 = (const Student*)b; // 对于 C 语言而言,强转语法可写可不写
// 后续表示大小规则的逻辑
}
排序 C 风格字符串数组
C 风格字符串本身就是字符指针,所以字符串的指针本身就是二级指针,这一点非常值得注意。1
2
3
4
5
6
7
8
9
10int my_cmp(const void *a, const void *b){
// 将 a 和 b 转换成 char* 类型,然后才可以进行比较操作
const char *s1 = *(const char **)a;
// 强转成二级指针再解引用一次,才能得到 char* 字符串的一级指针
const char *s2 = *(const char **)b;
// 注意:此时的强转语法是不能省略的。
// 因为通用指针类型是明确不能直接解引用的!!!
// 后续表示大小规则的逻辑
}