函数指针

函数具有可赋值给指针的物理内存地址,一个函数的函数名就是一个指针,它指向函数的代码。一个函数的地址是该函数的进入点,也是调用函数的地址。

1 定义

函数指针指的是指向函数的指针,函数指针指向某种特定的类型。而函数类型由它的返回类型和形参类型共同决定,与函数名无关。例如:

int add(int, int);		//定义了一个函数原型
int (*pf)(int, int);	//声明一个函数指针,未初始化

//可以使用typedef类型别名来简化
typedef int (*PF)(int, int);
PF pf2;		//声明一个函数指针

我们声明了一个函数,该函数的函数类型是int (int, int)
同时还声明了一个指向函数的指针 pf,该函数的参数是两个 int 类型,返回值是int类型。因此,函数指针 pf 可以指向一个类型为 *int (int, int)*的函数。

2 初始化

pf = add;		//pf指向名add的函数
pf = &add;		//等价的赋值语句,取地址符是可选的,

3 函数指针的使用

函数的调用可以通过函数名,也可以通过指向函数的指针来调用。函数指针还允许将函数作为变元传递给其他函数。例如:

3.1 普通调用

int sum1 = pf(3, 4);		//调用add函数
int sum2 = (*pf)(3, 4);		//等价的调用
int sum3 = add(3, 4);		//等价的调用

3.2 函数指针做形参

//第二个形参为函数类型,会自动转换为指向此类函数的指针  
Void fuc1(int a, int b, int pf(int,int));  
  
//等价的声明,显式的将形参定义为指向函数的指针  
Void func2(int a, int b, int (*pf)(int,int));  
Void func3(int a, int b, PF); 

形参中有函数指针的函数调用,例如:

pf = add;
pf2 = add;
func1(3, 4, add);	//add自动转化为指针
func2(3, 4, pf);
func3(3, 4, pf2); 

4 重载函数的指针

如果定义了指向重载函数的指针

int add(int, int);	
int add(double, double);

int (*pf3) (int, int) = add;	//pf3指向int add(int, int)

编译器通过指针类型决定使用哪个函数,指针类型必须与重载函数中的某一个精确匹配(返回类型,形参类型都完全匹配)。

5 返回指向函数的指针

使用typedef定义的类型别名 声明

typedef int (*PF) (int, int);
using PF2 = int (int, int);	//另一种等价方式,PF2是指针类型
using F = int (*) (int, int);	//	F是函数类型

PF func4(int);		

也可以直接声明

int (*func4(int))(int, int);

按照由内向外的顺序阅读此声明语句。func4 有形参列表,则func4是一个函数,其形参为 (int),func4 前面有 * ,所以 func4 返回一个指针,指针本身也包含形参列表(int,int),因此指针指向函数,该函数的返回值为int.

总结:func4 是一个函数,形参为(int),返回一个指向int(int,int)的函数指针。

6 C++函数指针

由于C++完全兼容C,则C中可用的函数指针用法皆可用于C++

6.1 C++其他函数(指针)定义方式及使用

6.1.1 typedef与decltype组合定义函数类型

typedef decltype(add) add2;  

decltype返回函数类型, add2是与add相同类型的函数,不同的是add2是类型,而非具体函数。

6.1.2 使用方法

add2* pf;//pf指向add类型的函数指针,未初始化  

typedef与decltype组合定义函数指针类型

typedef decltype(add)* PF2;	//PF2与PF意义相同  
PF2 pf;						// pf指向int(int,int)类型的函数指针,未初始化  

使用推断类型关键字auto定义函数类型和函数指针

auto pf = add;
auto *pf 

注意事项

指向不同函数类型的指针不存在转换规则。即一个函数指针只能指向其定义的函数类型。
//对于两个不同函数类型的函数
int add(int, int);			//函数类型是 int (int, int)
int add2(double, double);	//函数类型是 int (double, double)
double add3(int, int);		//函数类型是 double (int, int)

int (*pf)(int, int);	//函数指针 pf 只能指向int (int, int)类型的函数
pf = 0;		//可以为pf 赋值一个nullptr 或者 0,表示没有指向任何一个函数
pf = add;	//正确,
pf = add2;	//错误,	形参类型不匹配
pf = add3;	//错误,返回类型不匹配
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值