为什么要使用函数指针?
调用的灵活性和通用性。试想一下,我们在设计初期并不知道我们的函数的具体实现细节。例如,我们我们想要一个排序函数qsort,但是具体排序法则我们并不确定,是降序还是升序,采用什么算法都不清楚。这些问题是要在用户调用这个函数的时候才能够决定。于是调用者应该自己设计comparator函数,传给qsort函数。
便于面向对象编程。
例如我们设计一个结构体apple。我们除了设计出苹果的属性比如,数量、重量、颜色外,我们还要定义关于苹果的操作,比如,吃掉,种植,这时候我们可以使用函数指针。然后我们以后调用这个结构体的时候,可以采用a.eat(&b)的方式调用函数。
typedef struct apple{ |
语法
函数地址
函数的地址实际上就是函数名。这一点可以类比于数组。
声明
要声明指向特定类型的函数的指针,可以先编写这种函数的原型,然后用(*pf)代替函数名。或者采用C++11 的auto也能声明并初始化函数指针。
double pam (int); |
使用函数指针调用函数
double pam (int); |
直接把函数地址(即函数名)赋值给函数指针就行了,注意特征标和返回类型必须相同。然后采用(*pf)(4)这样的方式调用函数。实际上,C++也允许这样子使用函数指针:
pf(4);//这种形式好看且实用,但是没有显示出 使用函数指针调用函数 |
深入理解函数指针
阅读这一篇幅,需要您熟练掌握,C语言中的指针。
//一些函数原型 |
我们对于语法的了解不能仅仅潜于认识,对于这种
const double *(*(*pd)[3])(const double *,int) = &pa;
我们不光要认识,更要会使用,再次重温一遍,我们想要一个指向数组的指针,这个数组里的元素是函数指针。第一步,数组元素的类型是函数指针,所以壳子要有
const double *(* ···)(const double *,int)
第二步,指向数组的指针(*pd)[3]
,由于[]比*优先级高,所以我们必须采用(),否则*pd[3]
就是一个数组,数组的元素是指针。
第三步,结合得const double *(*(*pd)[3])(const double *,int) = &pa
使用typedef 简化
typedef const double *(* p_fun)(const double *,int); |
typedef
使得代码量减少很多,而且更容易理解