函数指针的定义
C/C++中函数指针是一种很重要的指针类型,同时由于函数指针本身和函数有很大的关系同时cpp中没有进行严格的要求使得函数指针与函数很容易混杂。
函数指针包含了以下的信息
1.指向的函数的返回值类型
2.指向的函数的参数数目
3.指向的函数的参数类型
/**************
*先定义一个简单的函数指针
*同时定义一个简单的指针函数作为对比
**************/
int (*p)(int a,int b); //函数指针
int* p(int a,int b); //指针函数
在函数指针的定义中,考虑运算符优先级,()运算符的优先级高于*运算符,因此如果以
int *p()的形式书写,p先和()结合成为函数,再和*结合,因此意味返回值为int型的指针
int(*p)()中*先和p结合生成一个指针,再和()结合说明指向的数据类型为一个函数。
函数指针与函数的关系
在cpp中函数指针和函数是一个较为混杂的概念,因为C++同时对以下的两种形式都支持
先回顾一下,其他指针在需要调用指向的数据的时候需要使用解引用,如
#include<iostream>
using namespace std;
int main()
{
int a=2;
int* p=&a;
*p=2;
cout<<p<<endl;
cout<<*p<<endl;
}
输出(基于visual studio2022)如下
00000026BFAFF9E4(x64下进行的编译所以为8个字节,32位计算机为4个字节)
2
即一个是指向的地址,一个是实际数值
但是函数指针在这方面相对更加宽松
1.如果p为一个函数指针,则(*p)()为指向的函数
2.如果p为一个函数指针,则p()为指向的函数
那么从另一个角度来看这个问题,实际上如果单独取用一个函数的函数名,其中存储的就是这个函数的地址(类似于指针),在传参的时候函数名可以直接传给函数指针。
函数指针的强制类型转换
函数指针由于其复杂性使得强制类型转换符变得很复杂
现在先来看一个很经典的问题(来自于《c语言陷阱与缺陷》)
(*((void(*)())0))()
先做一些解释:void(*)()为函数指针强制类型转换符,将0转化为一个指向返回值为空,参数列表为空的函数指针,再解指针为指向的函数进行使用。
因此一个函数指针的强制类型转化符为对应的函数指针省略指针名称
如下几组对应的例子:
int (*p)(double )
int(*)(double)
double (*b)(float ,int ,const char* )
double(*)(float,int,const char*)
函数指针作为函数参数
函数指针作为函数参数使得可以在函数中更加灵活的调用一类函数,而不会受到具体函数名的限制。但是同时函数指针用作函数参数在函数声明的过程中也会产生一定的麻烦。
先看下面一个例子
/*****************
*一个函数指针作为参数的函数
*****************/
double text(double(*fun)(double), double a)
{
double res;
res = ((*fun)(a + h) - (*fun)(a)) / h;
return res;
}
在函数指针作为函数参数的时候需要完整的表达出函数参数的所有信息。