高质量程序设计指南c++/c语言(33)--函数指针
函数类型由其返回类型和形参表确定,而与函数名无关。
// pf points to function returning bool that takes two const string references bool (*pf)(const string &, const string &);
*pf两侧的括号是必须的
// declares a function named pf that returns a bool * bool *pf(const string &, const string &);
1、指向函数的指针的初始化和赋值
在引用函数名但是又没有调用该函数时,函数名将被自动解释为指向函数的指针。
bool lengthCompare(const string &, const string &);
除了用作函数调用的左操作数以外,对lengthCompare的任何使用都将被解释为如下类型的指针
bool (*)(const string &, const string &);
typedef bool (* cmpFun)(const string &, const string &); cmpFun pf1 = 0; cmpFun pf2 = lengthCompare; pf1 = lengthCompare; pf2 = pf1;
函数指针只能通过同类型的函数或者函数指针或者0进行初始化和赋值。
cmpFun pf1 = lengthCompare;
cmpFun pf2 = &lengthCompare;
直接引用函数名等效于在函数名上应用取地址操作符。
2、通过指针调用函数
cmpFun pf = lengthCompare; lengthCompare("hi", "ss"); //direct call pf("ds", "sd"); //pf implicitly dereferenced (*pf)("sss", "sdd"); //pf explicitly dereferenced
3、函数指针形参
可以使用下面的两种形式
3.1、将形参定义为函数类型
void useBigger(const string &, const string &, bool (const string &, const string &)); void useBigger(const string &, const string &, bool f(const string &, const string &));
注意第三个形参。
3.2、将形参定义为函数指针
void useBigger(const string &, const string &, bool (*)(const string &, const string &)); void useBigger(const string &, const string &, bool (*f)(const string &, const string &));
4、返回指向函数的指针
// ff is a function taking an int and return a function pointer // the function pointed to returns an int and takes an int * and int int (* ff(int))(int *, int);
阅读函数指针声明的最佳方法就是从声明的名字开始从内向外理解。
要理解声明的定义,首先观察
ff(int)
将ff声明为一个函数,它带有一个int型的形参,该函数返回
int (*)(int *, int);
它是指向函数的指针。
使用typedef可使该定义简明易懂:
typeded int (*PF)(int *, int);
PF ff(int);
允许将形参定义为函数类型,但是函数的返回类型则必须是指向函数的指针,而不能是函数。
typedef int func(int *, int);//可以理解为把函数类型 int (int*, int)重命名为func void f1(func); //等价于void f1(int f(int*,int)), ok: f1 has a parameter of function type func f2(int); // error: f2 has a return type of function type func * f3(int); //ok: f3 returns a pointer to function type
5、指向重载函数的指针
extern void ff(double); extern void ff(unsigned int); void (*pf1)(unsigned int) = &ff; //void (*pf1)(unsigned int) = ff;
指针的类型必须与重载函数的一个版本精确匹配。如果没有精确匹配的函数,则对该指针的初始化或赋值都将导致编译错误:
// error: no match:invalid parameter list void (*pf2)(int) = &ff; // error: no match:invalid return type double (*pf3)(double); pf3 = &ff;