前言
在C语言的标准库中,有很多实用的函数可以为我们节省大量的开发时间和精力。其中一个非常重要且广泛使用的函数就是qsort()。qsort()函数是一个强大的排序函数,可以对各种类型的数据进行排序。在本篇博客中,我们将深入了解qsort()函数的用法和原理。
1.qsort()函数的声明
#include <stdlib.h>//所需头文件
void qsort(void* base, size_t num, size_t size, int (*cmp)(const void* e1, const void* e2));
该函数接受四个参数:
-
base:待排序数组的首元素地址。
-
num:待排序数组的元素个数。
-
size:每个元素的大小(字节数)。
-
cmp:比较函数的指针。
比较函数 cmp 是 qsort()函数的核心所在。它定义了排序的规则,告诉qsort()函数如何比较数组中的元素。比较函数需要满足以下条件: -
它返回一个整数值,该值表示两个元素的比较结果:
如果返回值小于0,表示第一个元素应该排在第二个元素之前。
如果返回值大于0,表示第一个元素应该排在第二个元素之后。
如果返回值等于0,表示两个元素相等,它们的相对顺序可以是任意的。
- 比较函数的参数为指向待比较元素的指针。
2.如何进行比较
为了说明qsort()函数的使用方法和原理,让我们通过一个示例来解释。假设我们有一个整型数组,我们想按照从小到大的顺序对它进行排序。首先,我们需要定义一个比较函数:
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2;
}
上述比较函数将两个待比较元素的地址强制转换为 int* 类型,然后比较两个整型数值的大小。接下来,我们可以调用qsort()函数对整型数组进行排序:
void test_int()
{
int arr[] = { 2, 4, 5, 6 ,5, 3 ,-1, 9 };
int num = sizeof(arr) / sizeof(arr[0]);
qsort(arr, num, sizeof(int), cmp_int);
for (int i = 0; i < num; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
在上述示例中,我们首先定义了一个整型数组 arr,包含了一些无序的整数。然后,我们计算出数组元素的个数,并将这些信息作为参数传递给qsort()函数,同时还传递了比较函数 cmp 的指针。最后,我们打印排序后的结果。
通过这个例子,我们可以深入理解qsort()函数的用法和原理。它是一个非常强大且灵活的排序函数,可以适用于不同类型的数据排序。只需定义相应的比较函数,即可实现对各种类型的数据排序。
3.其它类型的排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//void qsort(void* base, //待排序数组的第一个元素的地址
// size_t num, //待排序数组的元素个数
// size_t size,//待排序数组中一个元素的大小
// int (* cmp)(const void* e1, const void* e2)//函数指针-cmp指向了一个函数,这个函数是用来比较两个元素的
// //e1和e2中存放的是需要比较的两个元素的地址
// );
//1. 排序整型数组, 两个整型可以直接使用>比较
//2. 排序结构体数组,两个结构体的数据可能不能直接使用>比较
// 也就是不同类型的数据,比较出大小,方法是有差异的
//
//测试qsort排序结构体数据
struct Stu
{
char name[20];
int age;
};
//结构体数据怎么比较呢?
//1. 按照年龄比较
//2. 按照名字比较
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2;
}
int cmp_char(const void* p1, const void* p2)
{
return *(char*)p1 - *(char*)p2;
}
int cmp_stu_by_age(const void* p1, const void* p2)
{
return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
int cmp_stu_by_name(const void* p1, const void* p2)
{
return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p1)->name);
}
void test_struct()
{
struct Stu arr[] = { {"张三", 17}, {"张无", 15}, {"李四", 20}, {"王五", 16}};
int num = sizeof(arr) / sizeof(arr[0]);
qsort(arr, num, sizeof(struct Stu), cmp_stu_by_age);
for (int i = 0; i < num; i++)
{
printf("%s %d, ", arr[i].name, arr[i].age);
}
printf("\n");
qsort(arr, num, sizeof(struct Stu), cmp_stu_by_name);
for (int i = 0; i < num; i++)
{
printf("%s %d, ", arr[i].name, arr[i].age);
}
}
//测试qsort排整型数据
void test_int()
{
int arr[] = { 2, 4, 5, 6 ,5, 3 ,-1, 9 };
int num = sizeof(arr) / sizeof(arr[0]);
qsort(arr, num, sizeof(int), cmp_int);
for (int i = 0; i < num; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
//测试qsort排序结字符数据
void test_char()
{
char arr[] = { 'd', 't','Q', 'n' ,'r', 'b' ,'k', '*' };
int num = sizeof(arr) / sizeof(arr[0]);
qsort(arr, num, sizeof(char), cmp_char);
for (int i = 0; i < num; i++)
{
printf("%c ", arr[i]);
}
printf("\n");
}
int main()
{
test_int();
test_char();
test_struct();
return 0;
}
4.关于void*
//void* 类型的指针 - 不能进行解引用操作符,也不能进行+-整数的操作
//void* 类型的指针是用来存放任意类型数据的地址
//void* 无具体类型的指针
//
//int* char* 指针类型
int main()
{
char c = 'w';
char* pc = &c;
int a = 100;
//int* p = &c;
// char*
void* pv = &c;//char*
pv = &a;//int*
return 0;
}
总结:
本篇博客深入介绍了C语言标准库中的qsort()函数,它是一个非常实用的排序函数。我们了解到qsort()函数的四个参数及其使用方法,并着重介绍了比较函数的编写和使用。通过正确定义比较函数,我们能够对不同类型的数据进行排序。
掌握了qsort()函数的使用方法之后,我们可以在日常编程中更加高效地进行排序处理。希望本篇博客能够帮助读者深入理解qsort()函数,并在实际项目中充分发挥其排序的优势。