1 函数指针—指向函数的指针
函数指针是指向函数而非对象的指针。像其他指针一样,函数指针也指向某个特定的类型,函数类型由其返回类型以及形参表确定,而与函数名无关。例如:
bool (*pf)(const string &,const string &);
将pf声明为指向函数的指针,带有两个const string&类型的形参和bool类型的返回值。
注意: *pf两侧的圆括号是必须的。
2 用typedef简化函数指针的定义
typedef bool (*pFun)(const string&,const string&);
那么定义函数指针变量的时候就简约多了:
如果有函数bool lengthCompare(const string &,const string &);
pFun pf1 = 0; //不指向任何函数
pFun pf2 = NULL; //不指向任何函数
pFun pf3 = lengthCompare;
pFun pf4 = &lengthCompare;
pf2 = pf3;
注:直接引用函数名等效于在函数名上应用取地址操作符,即pf3与pf4是等价的;指向不同类型的函数指针之间不存在转换,即类型不同的话不能赋值等。
3 函数指针调用函数
pFun pf = lengthCompare;
lengthCompare("hello","world"); //直接调用方式
pf("hello","world"); //函数指针调用方式一
(*pf)("hello","world"); //函数指针调用方式二
方式一和方式二是一样的效果,可以使用解引用操作符或者不使用都可以。
4 函数指针形参
函数指针可以作为函数的形参。
形参书写方式一:bool (const string &,const string &)
形参书写方式二:bool (*)(const string &,const string &)
5 返回函数指针
函数可以返回函数指针,如:
int (&pf(int))(int *,int);
该函数返回int (*)(int *,int);
是一个指向函数的指针,所指向的函数返回int型并带有两个分别是int*型和int型的形参。也可以使用typedef简化定义:
typedef int(*pF)(int*,int);
pF ff(int); //ff返回函数指针
6 指向重载函数的指针
必须要参数列表和返回值匹配。
7 函数指针的应用—回调函数
很简单的一个例子,对于排序,可以按照从小到大的排序方式,或者按照从大到小的排序方式,我们可以写一个函数来实现排序,但是如果想要这两种排序方式都实现,那么就可以考虑几种方式实现了:
- 写两个函数分别来实现。这个明显代码量多了,而且函数个数也多了,且每个函数里的代码量都是相当的。
- 写一个函数,然后再加个参数flag,来判断到底是要按哪种方式来排序。这种方式其实本质是将方式1的代码合并了,也没少什么代码,不是那么灵活。
- 通过回调函数来实现。这个可以动态的来选择到底是要按哪种方式来排序。
//-----------------------------------------------
//文 件:callback.cpp
//作 者:yicm
//功 能:用一个函数动态的实现按ID排序,按AGE排序
//创建日期:2015-10-12
//修改日期:2015-10-13
//-----------------------------------------------
#include <stdio.h>
typedef int student_id;
typedef int student_age;
typedef struct _Student{
student_id id;
student_age age;
}Student;
//类型重定义:函数指针类型
typedef bool (*pFun)(Student, Student);
//-----------------------------------------------
//冒泡排序法:能够按AGE或ID排序,用同一个函数实现
//-----------------------------------------------
int sort(Student stu[],const int num,pFun fun)
{
Student temp;
for(int i = 0; i < num; ++i){
for(int j = 0; j < num - i -1; ++j){
if((*fun)(stu[j],stu[j+1])){
temp = stu[j];
stu[j] = stu[j+1];
stu[j+1] = temp;
}
}
}
}
//-----------------------------------------------
//回调函数:比较年龄
//-----------------------------------------------
bool CompareAge(Student stu1,Student stu2)
{
//更改从大到小还是从小到大的顺序,只需反一下。
if(stu1.age < stu2.age)return true;
return false;
}
//-----------------------------------------------
//回调函数:比较id
//-----------------------------------------------
bool CompareId(Student stu1,Student stu2)
{
//更改从大到小还是从小到大的顺序,只需反一下。
if(stu1.id < stu2.id)return true;
return false;
}
int main()
{
Student stu[] = {{1103,24},
{1102,23},
{1104,22},
{1107,25},
{1105,21}};
pFun fun = CompareAge;
int size = sizeof(stu)/sizeof(Student);
sort(stu,size,fun);
for(int i = 0; i < size; ++i){
printf("%d %d\n",stu[i].id,stu[i].age);
}
return 0;
}