成为C++高手之回调函数
2016-05-19 05:03
405 查看
上一节的排序函数只能正向排序,那我们需要反向排序怎么办?可以增加一个参数嘛,传入TRUE,就表示要正向排,传入FALSE,就表示要反向排。要改变排序方向,只需改变两项比较时是用大于号还是小于号即可。但是这里有更高级的玩法,即传入的参数不是一个BOOL型值,而是一个函数指针。
函数名本身就是一个指针,调试时看函数名,其值就是一个地址。但在逻辑上不能把函数名叫函数指针,必须另创建一个指针指向这个函数,通过这个指针调用函数才叫回调。
函数指指与变量指针没实质区别,都是保存一个表示内存位置的整数,但编译器必须能区分指针的类型才行。所以函数指针在定义时必须指定其类型。所以要为函数定义类型。函数类型是由函数返回值类型、参数数量、参数类型决定,与函数的实现无关。就是长一个样的函数都是同一类型。
我们这里增加一个参数,传入的函数指针指向一个比较函数,仅代替“arr[j]>arr[j+1]”部分。比较函数必须有两个参数指向要比较的元素的序号,返回必须是BOOL型数据,表示比较结果。if语句跟据比较函数返回值决定是否交换位置。
改用回调函数有什么好处呢?此处并不明显,甚至更麻烦。但试想这种情况:如果我们数组中不是简单数值,而是一个结构。比如扑克牌,一张牌至少有两个属性:花色和点数,对应到结构中就是两个成员变量。当牌发到玩家手中后,是乱序的,玩家需要整理好其顺序。不同的游戏有不同的排序规则,那我们可以为每种游戏规则都写一个不同的排序函数,或者这样做:排序函数固定,只为每种不同的游戏写不同的比较函数。这增强了排序代码的重用性。
上一篇:成为C++高手之for循环
函数名本身就是一个指针,调试时看函数名,其值就是一个地址。但在逻辑上不能把函数名叫函数指针,必须另创建一个指针指向这个函数,通过这个指针调用函数才叫回调。
函数指指与变量指针没实质区别,都是保存一个表示内存位置的整数,但编译器必须能区分指针的类型才行。所以函数指针在定义时必须指定其类型。所以要为函数定义类型。函数类型是由函数返回值类型、参数数量、参数类型决定,与函数的实现无关。就是长一个样的函数都是同一类型。
我们这里增加一个参数,传入的函数指针指向一个比较函数,仅代替“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 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中进制知识汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- C语言实现选择排序、冒泡排序和快速排序的代码示例
- 探讨C语言的那些小秘密之断言