这里记录一下函数指针的学习。c++
函数指针顾名思义就是指向一个函数的指针,函数指针能够理解成指向函数入口地址的指针。函数指针的定义以下:数组
bool (*pf)(int,int);//指向一个形参为(int,int),返回值为bool值的指针,记得使用括弧 bool* pf(int,int);//该形式并非函数指针,而是返回一个指针类型的函数
使用以下:函数
bool (*pf)(int,int); bool check(int a,int b){ return a==b; } bool bigger(int a,int b){ return a>b; } int main(int argc, char* argv[]) { int a=34,b=34; pf=check;//等价于pf=✓ cout<<pf(a,b)<<endl;//pf(a,b)等价于(*pf)(a,b) b=32; cout<<pf(a,b)<<endl; pf=bigger; cout<<pf(a,b)<<endl; b=34; cout<<pf(a,b)<<endl; return 0; } //输出结果 //1 //0 //1 //0
对于函数指针的定义而言,理解起来有点费劲,使用C++ Primer书中的解释理解:学习
对于函数指针,能够从名字开始观察,pf前面有个*,所以pf是指针;右侧是形参列表,标识pf指向的是一个函数;再观察左边,返回的是一个bool类型。所以pf就是一个指向函数的指针,该函数有两个形参,返回类型为bool值。指针
函数指针也能够充当形参在方法中传入:code
bool bigger(int a,int b){ return a>b; } bool (*pf)(int,int); void testConfig(int k,bool pf(int a,int b)){ bool value=pf(12,1); cout<<k<<" "<<value<<endl; } bool check(int a,int b){ return a==b; } int main(int argc, char* argv[]) { int a=34,b=34; int *p=&a; testConfig(12, bigger); testConfig(12, check); return 0; } //result //12 1 //12 0
因为使用上述方式声明函数指针显得冗长繁琐,因此能够经过typedef以及decltype来简化咱们的代码:ip
bool check(int& a,int b){ return a==b; } bool bigger(int a,int b){ return a>b; } bool (*pf)(int,int); void testConfig(int k,bool pf(int a,int b)){ bool value=pf(12,1); cout<<k<<" "<<value<<endl; } typedef int(*po) (int,int); decltype(bigger) *dePo; int main(int argc, char* argv[]) { int a=34,b=34; int *p=&a; testConfig(12, dePo); testConfig(12, check); return 0; }
上述代码中能够看到,使用dePo代替了指向bigger()函数的函数指针。编译器
须要注意的是decltype返回函数类型,此时是不会讲函数类型自动转换为指针的,须要显式在在dePo前面加个*来标明对应为指针类型。编译
tip:class
须要注意decltype()和decltype(())的区别(推导四规则):
int i=10; decltype(i) a; //a推导为int decltype((i))b=i;//b推导为int&,必须为其初始化,不然编译错误
和数组相似,虽然不能返回一个函数,可是能返回指向函数类型的指针。须要注意的是,咱们必须把返回类型写成指针的形式,编译器不会自动的将函数返回类型当作对应指针的类型处理:
bool bigger(int a,int b){ return a>b; } using PF= bool (*)(int,int);//PF为函数指针 using PFD=bool(int,int);//PFD是函数类型,不是指针 PFD *f1(int){//显示指定返回类型为函数指针 return bigger; } PF f2(int,bool pf(int,int)){ // ... return bigger; }
咱们也能够不用using来直接声明返回的函数指针:
bool (*f3(int a))(int b,int c){ return bigger; }
这样就有点绕了,能够按照由内向外的顺序进行阅读,f3有形参a,说明是一个函数,前面有一个*号,因此返回的是一个指针,而指针有参数b,c,说明这个指针指向一个函数,这个函数的返回值为布尔值。
使用尾置类型可能更好理解一些:
auto f4(int)->int(*)(int,int);