目录
1.回调函数定义
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个
函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数
的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进
行响应。
2.qsort实现整型,结构体排序
首先先来复习一遍冒泡排序
int i = 0;
for (i = 0; i < sz; 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;
}
}
}
很简单,就是两两相邻进行比较,按照降序或者升序进行排列即可。
库函数中有一个 qsort的一个函数,可以对数组进行排序,也用到了回调函数。
通过cplusplus看到,
qsort函数的参数是
第一个void* base 指的是待排序数组的起始地址,size_t num是这个数组的元素个数,size_t size是一个元素的大小,int(*compar)(const void*,const void*)这是一个函数指针,返回类型是int,名字是compar,函数参数是两个void*。在这里多次用到void是因为qsort函数不仅仅可以将int类型进行排序,字符型,结构体等等都是可以的,所以用void来传递,这样就可以接收各种类型的数组了。但是这样的void*指针不能做修改。
对于qsort的参数,前面三个都没什么问题,最后一个比较函数如下:
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
参数是两个void*类型,到了函数主题是需要强制类型转换成(int*)l类型,这return的值根据qsort的描述就是前者大就是返回值大于1,后者大返回值小于1,如果相等那就返回0.下图是cplusplus的qsort中的cmp函数的返回值的解释。
所以综合起来代码就很简单明了了。这里就先不给代码,对于上面的qsort函数的模拟使用只限于整型,现在再来一个对于结构体的排序。下面的代码是结构体的定义。
struct Stu
{
char name[20];
int age;
};
对于结构体的排序,可以从name和age两个内容来排序。age就是纯粹的比大小,name是字符串对应的每一位进行比较。
这是两个比较方法的函数,看看就懂,容易理解。
int cmp_stu_by_name(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->name - ((struct Stu*)e2)->name;
}
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
【总体代码】
#include<stdio.h>
#include<string.h>
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void test1()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_name(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->name - ((struct Stu*)e2)->name;
}
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
void test2()
{
struct Stu s[3] = { {"zhangsan",20},{"lisi",30},{"wangwu",40} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
int main()
{
test1();
return 0;
}
对于int类型的结果直接打印就可可以,但是结构体类型就需要调试着去看结果。
通过调试发现,s[3]结构体数组中的元素会发生排序。
3.改造的冒牌排序(qsort)
改造冒泡排序函数,使得这个函数可以排序任意指定的数组.
下面的是整个代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void bubble_sort(void* base,
size_t sz, size_t width,
int(*cmp)(const void* e1, const void* e2))
{
size_t i = 0;
for (i = 0; i < sz - 1; i++)
{
size_t j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
Swap((char*)base+j*width,(char*)base+(j+1)*width,width);
}
}
}
}
//使用我们自己写的bubble_sort函数排序整型数组
void test()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
test();
return 0;
}
在这里我不过多做解释了,所有的内容解释都放在了下面的图中。