一、格式
例如:
- //指针名为pf,指向一个返回值为bool,参数为两个const string&的函数
- bool (*pf)(const string&, const string&);
- //这个不是函数指针,而是一个返回值为bool*的pf函数
- bool *pf(const string&, const string&);
二、函数指针的赋值
- 可以直接将函数名赋值给函数指针,或者在函数名前加&符号都可以
- bool lengthCompare(const string&, const string&);
- bool (*pf)(const string&, const string&);
- int main()
- {
- pf = lengthCompare; //正确
- pf = &lengthCompare;//正确
- return 0;
- }
三、通过函数指针调用函数
调用方式
- 如果pf是一个函数指针,那么*pf就是该指针所指向的函数,所以(*pf)()就是调用该函数
- ANSI C标准允许程序员将(*pf)()简写为pf(),但是一定要记住这种写法是一种简写形式
演示案例
- bool lengthCompare(const string&, const string&);
- bool (*pf)(const string&, const string&);
- int main()
- {
- pf = lengthCompare;
- bool b1 = (*pf)("hello", "goodbye");//相当于在调用lengthCompare("hello","goodbye")
- bool b2 = pf("hello","goodbye"); //同上,但是注意这是简写形式
- return 0;
- }
四、函数指针的注意事项
- 函数指针可以赋值为空或者0
- 函数指针必须指向与指针返回值类型以及参数相同的函数
五、重载函数的指针
- 定义一个重载函数指针时,必须有相对应匹配的重载函数与指针匹配
- void ff(int*);
- void ff(unsigned int);
- void (*pf)(int*)=ff; //正确,指向void ff(int*);
- void (*pf2)(int)=ff; //错误,没有匹配的函数
- double (*pf3)(unsigned in)=ff; //错误,没有匹配的函数
六、函数/函数指针传参
- 一个函数的形参为函数或者函数指针时,调用这个函数时,函数形参可以为函数本身也可以为函数指针(调用时本质上传入的都是函数的指针)
- bool lengthCompare(const string&, const string&);
- void useBigger(const string&, const string&, bool pf(const string&, const string&));
- void useBigger2(const string&, const string&, bool (*pf)(const string&, const string&));
- int main()
- {
- bool (*pf)(const string&, const string&);
- pf = lengthCompare;
- useBigger("hello", "goodbye",lengthCompare);
- useBigger("hello", "goodbye", pf);
- useBigger2("hello", "goodbye", lengthCompare);
- useBigger2("hello", "goodbye", pf);
- return 0;
- }
七、函数与函数指针取别名
- 可以使用typedef和decltype来简化函数或函数指针的声明
- 注意:decltype返回的是函数类型,而不是指针类型,所以Funcp2前面还需要加上*
bool lengthCompare(const string&, const string&);
//Func和Func2都是函数类型
typedef bool Func(const string&, const string&);
typedef decltype(lengthCompare) Func2;
//FuncP和FuncP2都是函数指针类型
typedef bool(*FuncP)(const string&, const string&);
typedef decltype(lengthCompare) *FuncP2;
void useBigger(const string&, const string&, Func);
void useBigger2(const string&, const string&, FuncP);
int main()
{
bool (*pf)(const string&, const string&);
pf = lengthCompare;
useBigger("hello", "goodbye",lengthCompare);
useBigger("hello", "goodbye", pf);
useBigger2("hello", "goodbye", lengthCompare);
useBigger2("hello", "goodbye", pf);
return 0;
}
八、返回函数的指针
- 函数和数组一样不能直接通过返回值返回,而需要通过指针返回
格式一:
- 下面是原始的定义方法,比较繁琐
- 意义为:f1函数的参数为int,返回值为函数指针类型,该函数指针指向的函数返回值为int,参数为int*和int
int (*f1(int))(int*, int); 格式二:
- using F = int(int*, int); //F为函数类型
- using PF = int(*)(int*, int);//PF为函数指针类型
- PF f1(int); //f1函数返回一个函数指针,该指针指向的函数返回值为int,参数为int*和int
- F* f1(int); //同上
- F f1(int); //错误,F为函数类型,不能直接返回
格式三:
auto f1(int)->int(*)(int*, int);
九、将auto和decltype用于函数与函数指针类型
- 将我们知道一个函数的返回值为某种函数指针类型时,可以使用decltype简化书写
演示案例
- 例如下面的getFcn函数返回值为sumLength函数指针类型,则可以使用下面的方法
- 注意:decltype返回的是函数类型,所以还需要加上指针
- string::size_type sumLength(const string&, const string&);
- string::size_type largerLength(const string&, const string&);
- decltype(sumLength) *getFcn();