回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
在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代表第一个指针指向的值排前面,否则后面的指针指向的值排前面。=_=
本文出自 “Pzd流川枫” 博客,请务必保留此出处http://xujiafan.blog.51cto.com/10778767/1722310