函数名本身就是函数的地址。
假设有一个函数think()
,则think
就是该函数的地址。
要将函数作为参数进行传递,必须传递函数名。
process(think); //传递的是函数地址
process(think()); //传递的是函数的返回值
在声明指向函数的指针时,要声明指针指向的函数的类型,即声明应指定函数的返回值类型和参数列表。
假设有一函数,原型如下:double pam(int);
则正确的指针声明如下:double (*pt)(int)
其中,(*pt)
是函数,pt
是函数指针。
在正确的声明了指针之后,我们就可以将相应的函数的地址赋给它:
pt=pam
前面指出,(*pt)
是函数,与pam作用相同,因此使用的时候直接将它看作函数名即可。
double pam(int);
double (*pt)(int);
pt=pam;
double x=pam(10);
double y=(*pt)(10);
double z=pt(10); //also valid
假设我们需要设计一个名为estimate()
的函数,用来计算运行指定行数代码所需要的时间,其中的算法由程序员自己设计决定。
假设程序员设计了两种计算时间的算法,分别为pam()
和betsy()
,其定义如下:
double pam (int lens){
return lens*1.5;
}
double betsy(int lens){
return lens*2.0;
}
则函数estimate()
直接将上面两个函数作为参数,使用如下格式:
estimate(pam,code);
estimate(betsy,code);
而函数estimate()
的声明和定义如下:
void estimate(double (*pf)(int),int lens){
cout<<lines<<"lines will take:";
cout<<(*pf)(lens)<<"hours";
}
其中,pf是指向函数的指针,(*pf)就是调用传进来的函数参数。
假设有下面这些函数原型,他们的参数列表和返回值类型都是相同的。
const double *f1(const double ar[],int n);
const double *f2(const double [],int n);
const double *f3(const double *,int n); //在函数原型中可以省略标识符ar
如果要声明一个指针p1,指向上面三个函数之一,则声明如下:
const double *(*p1)(const double *,int)=f1; //声明的同时初始化
也就是将函数名f1换成了(*p1)。
使用C++11的自动类型推断功能,代码要简单的多:
auto p2=f2;
也可以声明一个指针数组,同时初始化:
const double *(*pa[3])(const double *,int)={f1,f2,f3};
注意,此时不可以使用auto进行声明,因为auto只能用于单值初始化。
但是声明完pa后,可以用auto声明同样类型的数组:auto pb=pa;
可以使用typedef在程序的开头为函数指针声明一个别名:
typedef const double *(*p_fun)(const double *,int);
//使用p_fun别名来简化代码
p_fun p1=f1;
p_fun pa[3]={f1,f2,f3};
C++ Primer Plus 第六版 中文版