回调函数是什么?
- 回调函数就是一个
通过函数指针调用的函数
。 - 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数。回调函数
不是
由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的
,用于对该事件或条件进行响应。
qsort使用举例
这个qsort函数有4个参数:
void qsort(void* base, size_t num, size_t size, int (*compar)(const void*, const void*));
- 第一个参数是指向待排序的第一个元素
- 第二个参数是待排序的元素个数
- 第三个参数是待排序的数组元素的大小(单位是字节)
- 第四个参数是比较两个元素
- 这里有个void*的指针类型,这个指针类型是
通用指针类型
,这个指针类型可以接收任意类型数据的地址,就可以理解成指针垃圾桶,谁的地址都可以往里扔~~ - 是一个无具体类型的指针,所以就不能+1,也不能解引用
我们也介绍完了这个函数,我们来使用一下
写出我们的主函数:
int main() { int arr[] = { 3,2,5,6,8,7,9,1,4 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); for (size_t i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
- 下面这里就剩下一个比较函数了,怎么写呢?我们再来看一个网站上面的介绍~~
- 这个函数能够比较e1和e2指向的两个元素,并给出返回值~~
- 我们也就按照上面的案例来写~~
int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; }
- 现在我们来看已经完美排序了~~
qsort函数的模拟实现
使用回调函数,模拟实现qsort(采用冒泡的方式)。
- 今天我们使用冒泡排序,来实现一个对任意类型能够排序的函数
- 我们先来实现一个整形的冒泡排序,然后再进行改造~~
void bubble_sort(int arr[], int sz) { int i = 0; for ( i = 0; i < sz - 1; i++) { int j = 0; for (j = 0; j < sz - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 3,2,5,6,8,7,9,1,4 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); for (size_t i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
接下来我们开始改造~~
- 改造参数 – 让这个函数能够接受任意类型的数据
- 改造比较方法 – 让函数能够在排序时,比较不同类型的数据
- 交换的代码也需要修改
- 我们来看完整代码
void print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } } void Swap(void* p1, void* p2, int size) { int i = 0; for (i = 0; i < size; i++) { char tmp = *((char*)p1 + i); *((char*)p1 + i) = *((char*)p2 + i); *((char*)p2 + i) = tmp; } } void bubble(void* base, int count, int size, int(*cmp)(void*, void*)) { int i = 0; int j = 0; for (i = 0; i < count - 1; i++) { for (j = 0; j < count - i - 1; j++) { if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0) { Swap((char*)base + j * size, (char*)base + (j + 1) * size, size); } } } } int cmp_int(const void* e1,const void* e2) { return *(int*)e1 - *(int*)e2; } void test1() { int arr[] = { 3,2,5,6,8,7,9,1,4 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), cmp_int); print_arr(arr,sz); } int main() { test1(); return 0; }
- 可以看到,我们对整形的排序也成功了