您的位置:首页 > 编程语言 > C语言/C++

成为C++高手之回调函数

2016-05-19 05:03 405 查看
上一节的排序函数只能正向排序,那我们需要反向排序怎么办?可以增加一个参数嘛,传入TRUE,就表示要正向排,传入FALSE,就表示要反向排。要改变排序方向,只需改变两项比较时是用大于号还是小于号即可。但是这里有更高级的玩法,即传入的参数不是一个BOOL型值,而是一个函数指针。

函数名本身就是一个指针,调试时看函数名,其值就是一个地址。但在逻辑上不能把函数名叫函数指针,必须另创建一个指针指向这个函数,通过这个指针调用函数才叫回调。

函数指指与变量指针没实质区别,都是保存一个表示内存位置的整数,但编译器必须能区分指针的类型才行。所以函数指针在定义时必须指定其类型。所以要为函数定义类型。函数类型是由函数返回值类型、参数数量、参数类型决定,与函数的实现无关。就是长一个样的函数都是同一类型。

我们这里增加一个参数,传入的函数指针指向一个比较函数,仅代替“arr[j]>arr[j+1]”部分。比较函数必须有两个参数指向要比较的元素的序号,返回必须是BOOL型数据,表示比较结果。if语句跟据比较函数返回值决定是否交换位置。

#include <stdio.h>
//定义比较函数类型
typedef int (*CompareFunc)(int *,int ,int );
//前置声明排序函数,第三个参数是比较函数类型
void sort(int * ,int ,CompareFunc);

//返回非0数表示比较成功,返回0表示失败
int compare1(int *arr,int a,int b){
return arr[a]>arr[b];
}
int compare2(int *arr,int a,int b){
return arr[a]<arr[b];
}

int main(int argc, const char * argv[]) {

int arr[]={22,33,45,1,2,7,66,554,23424234,22};

//排序,第三个参数可以传入两个比较函数之一
sort(arr,sizeof(arr)/sizeof(int),compare1);

//打印排序后的数组
for(int i=0;i<sizeof(arr)/sizeof(int);i++){
printf("%d ",arr[i]);
}

return 0;
}

//第一个参数是要排序的数组,第二个是数组两元素的数量
void sort(int *arr ,int count,CompareFunc compare_func){
int i;
//外层循环是倒着来的
for(i=count-1;i>0;i--){
int j;
for(j=0;j<i;j++){
//调用比较函数进行比较
if(compare_func(arr,j,i)){
int tmp = arr[j];
arr[j]=arr[i];
arr[i]=tmp;
}
}
}
}


改用回调函数有什么好处呢?此处并不明显,甚至更麻烦。但试想这种情况:如果我们数组中不是简单数值,而是一个结构。比如扑克牌,一张牌至少有两个属性:花色和点数,对应到结构中就是两个成员变量。当牌发到玩家手中后,是乱序的,玩家需要整理好其顺序。不同的游戏有不同的排序规则,那我们可以为每种游戏规则都写一个不同的排序函数,或者这样做:排序函数固定,只为每种不同的游戏写不同的比较函数。这增强了排序代码的重用性。

上一篇:成为C++高手之for循环
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言