什么是回调函数?
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
接下来让我们运用qsort函数来加深对回调函数的理解;
qsort是编译器函数库自带的快速排序函数。
使用qsort()排序并用 bsearch()搜索是一个比较常用的组合,使用方便快捷。
qsort 的函数原型是
void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));
各参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针 其中base是排序的一个集合数组,num是这个数组元素的个数,width是一个元素的大小,comp是一个比较函数。比如:对一个长为1000的数组进行排序时,int a[1000]; 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名。qsort(a,1000,sizeof(int),comp);
int comp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
Comp 函数编写作用是由小到大排序,这里只是需要comp函数返回正值、负值或者零即可。
前面介绍了qsrot函数,我们知道了我们知道qsort是通过回调函数来实现其功能,故而我们通过回调函数可以排序各种类型的数据;
代码实现:
#include
#include
int cmp1(const void *a,const void *b)
{
return *(int*)a - *(int*)b;//a>b返回正值
}
int cmp2(const void *a,const void *b)
{
return *(char*)a - *(char*)b;
}
int cmp3(const void *a, const void *b)
{
return strcmp(*(char **)a,*(char **)b);
}
int cmp4(const void *a, const void *b)
{
return *(double*)a - *(double*)b;
}
int main()
{
int a[] = { 0,1,9,3,4,5,6,7,8,2 };//整形
char b[] = { 'b','a','c','d','e' };//字符
char *str[] = { "bbbb","aaaa","dddd","cccc" };//字符串
double arr[] = { 1.0,6.0,2.0,3.3,5.5 };//浮点型
qsort(a, 10, sizeof(int), cmp1);
qsort(b, 5, sizeof(char), cmp2);
qsort(str, 4, sizeof(char*), cmp3);
qsort(arr, 5, sizeof(double), cmp4);
int i = 0;
for (i = 0;i < 10;i++)
{
printf("%d ", a[i]);
}
printf("\n");
for (i = 0;i < 5;i++)
{
printf("%c ", b[i]);
}
printf("\n");
for (i = 0;i < 4;i++)
{
printf("%s ", str[i]);
}
printf("\n");
for (i = 0;i < 5;i++)
{
printf("%f ", arr[i]);
}
printf("\n");
system("pause");
return 0;
}
运行结果如下:
通过以上这些回调函数,我们可以得出写这些回调函数的规律:
1)返回类型 int ,其实是将两个参数比较完的结果返回;
2)参数类型 void*,void *可以接受任意类型的实参;
3)比较两个参数的大小时,需将其转换成相应的类型,例如数组是 int,此时参数需强转成(int *);
4)注意:在比较字符串大小时,不能将其直接比较,在这里需要使用strcmp函数
模仿qsort的功能实现一个通用的冒泡排序。
代码如下:
#include
#include
int cmp2(const void *x,const void *y)
{
return *(int *)x - *(int *)y;
}
int cmp1(const void *a, const void *b)
{
return strcmp(*(char **)a, *(char **)b);
}
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 - 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 main()
{
int i = 0;
int a[] = { 4,5,6,7,8,9,1,2,0,3 };
char *s[5] = { "aaaa", "dddd", "iiii", "cccc", "ffff" };
Bubble(a, sizeof(a) / sizeof(a[0]), sizeof(int), cmp2);
Bubble(s,sizeof(s)/sizeof(*s), sizeof(char *), cmp1);
for (i = 0; i
结果如下: