回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
在C语言库中,有这个函数qsort() 定义在头文件:#include <stdlib.h>
它接收四个参数:
void qsort( void *base,
size_t num,
size_t width,
int ( *compare )(const void *elem1, const void *elem2 ) );
【参数】1:vioid *base---要排序的数组的首地址
2:size_t num---数组中元素个数
3:size_t width--数组中元素所占空间大小(字节数)
4:int ( *compare )(const void *elem1, const void *elem2 ) )---比较函数的函数指针
下面用回调函数实现整形数组冒泡排序:
#include <stdio.h> #include <stdlib.h> int int_cmp(const void *n1,const void *n2) { return (*(int *)n1-*(int *)n2); } int main() { int arr[]={1,3,5,7,9,2,4,6,8,0}; int len=sizeof(arr)/sizeof(arr[0]); int sz=sizeof(int); int i=0; qsort(arr,len,sz,int_cmp); for (i=0;i<len;i++) { printf("%d\n",arr[i]); } return 0; }
结果:
qsort()函数,只需要传递四个参数,分别是要排序的数组的首地址,数组中元素个数,数组中元素所占空间大小(字节数),比较函数的函数指针。当比较函数返回正数时,交换两个元素次序,返回其他,则不交换。所以这个函数就很好实现了。下面是我的实现:
#include <stdio.h> typedef struct Stu { int score; char name[20]; }Stu;//定义结构体 /*整形比较函数*/ int int_cmp(const void *elem1,const void *elem2) { return *(int *)elem1-*(int *)elem2; } /*字符串比较函数*/ int str_cmp(const void *elem1,const void *elem2)//字符串比较函数 { if (strcmp((char *)(*(int *)elem1),(char *)(*(int *)elem2))>0) return 1; else return -1; } /*结构体比较函数*/ int stu_cmp(const void *elem1,const void *elem2)//结构体比较函数 { if (((Stu *)elem1)->score>((Stu *)elem2)->score) return 1; else return -1; } /*交换元素*/ void swap(void *p1,void *p2,int size) { int i=0; for (i=0;i<size-1;i++) { char tmp=*((char *)p1+i); *((char *)p1+i)=*((char *)p2+i); *((char *)p2+i)=tmp; } } /*回调函数*/ void bubble(void *base, int num, int width, int(*compare )(const void *elem1, const void *elem2 )) { int i=0; int j=0; for (i=0;i<num;i++) { for (j=0;j<num-i-1;j++) { if (compare((char*)base+j*width,(char *)base+(j+1)*width)>0)//判断成功 { swap((char *)base+width*j,(char *)base+width*(j+1),width);//交换元素 } } } }
测试:
/*整形测试*/ int main() { int arr[]={1,3,5,7,9,2,4,6,8,0}; int len=sizeof(arr)/sizeof(arr[0]); int sz=sizeof(int); int i=0; bubble(arr,len,sz, int_cmp); for (i=0;i<len;i++) { printf("%d\n",arr[i]); } return 0; }
结果:
/*字符串测试*/ int main() { char *arr[]={"aaaa","abcd","aabc","rose"}; int len=sizeof(arr)/sizeof(arr[0]); int sz=sizeof(char *); int i=0; qsort(arr,len,sz, str _cmp); for (i=0;i<len;i++) { printf("%s\n",arr[i]); } return 0; }
结果:
/*结构体测试*/ int main() { Stu stu[]={{80,"paul"},{90,"rose"},{100,"curry"},{99,"kobe"}}; int i=0; bubble(stu,4,sizeof(Stu), stu_cmp); for (i=0;i<4;i++) { printf("%s %d\n",stu[i].name,stu[i].score); } return 0; }
结果:
所以,qsort()函数,只需要传递四个参数,分别是要排序的数组的首地址,数组中元素个数,数组中元素所占空间大小(字节数),比较函数的函数指针。 ^_^ (回调函数实现冒泡排序)
这里还得说明的是,qsort函数中最后一个参数是函数指针:
int ( *compare )(const void *elem1, const void *elem2 ) )
这个就是定义了一个接口,你必须实现如此定义的一个比较函数,并将你的比较函数的地址传递给qsort,qsort在排序时调用你定义的比较函数进行比较,以确定两数据的先后,而如何安排量数据的先后由你决定。而且你的比较函数必须返回-1或者1,-1代表第一个指针指向的值排前面,否则后面的指针指向的值排前面。=_=