[ C++ ] — 函数指针

一、函数名 与 &函数名

函数名就是函数的地址

void func(void) {
    
}
int main()
{
    cout << func << endl;
	cout << &func << endl;
    return 0;
    
}

输出:

00D2142E
00D2142E

函数名 和 &函数名 的输出是一样的,但 &函数名 是什么?

void func() {

}
int main()
{
	void (*fp)(void); 
	cout <<typeid(func).name() << endl;
	cout<< typeid(&func).name()<<endl;
	cout <<typeid(fp).name();
}

输出:

void __cdecl(void)
void (__cdecl*)(void)
void (__cdecl*)(void)

可以看到

  • func的类型是void(void)
  • &func的类型是 void(*)(void),与同类型的函数指针的类型相同

若把函数名看作是函数的地址,可以把 &函数名 看成是该类型的函数指针。

fp可以指向其他函数,并调用它

void func2() {
	cout << "I'm func2";
}
int main()
{
	void (*fp)(void); 
	fp = func2;
	fp();
}
I'm func2

但很显然,&func并不是一个指针变量
在这里插入图片描述
所以,可以将 &函数名 看作为指向该 函数类型函数指针类型

二、函数指针

1、声明

一般来说,声明指针时必须指定确定指向的类型,函数指针也是如此。当声明函数指针时,需要指定指向的函数类型,包括:

  • 返回类型
  • 参数列表
double (*fp)(int); //返回类型为double,参数为int类型

也可以用typedef

typedef double (*FP)(int); //FP是指向“返回值为double类型,参数为int类型”的一类函数的指针类型
FP fp; //声明一个此类指针
double cal(int); //函数声明
fp=cal; //指针赋值

2、函数指针调用函数

double (*fp)(int);
...
double result= (*fp)(5); //调用

3、作为函数参数传递

void myFunc(double (*fp)(int)); //函数指针作为参数传递
int sum(int a,int b) {
    return a+b;
}
void myFunc(int a, int b, int (*fp)(int, int)) {
    cout << (*fp)(a,b)<<endl;
}
int main()
{
    myFunc(1,2, sum);
    return 0;
}

输出:3
如果用typedef的话,程序的可读性会更好

typedef int (*FP)(int, int);
int sum(int a,int b) {
    return a+b;
}
void myFunc(int a, int b, FP fp) {
    cout << (*fp)(a,b)<<endl;
}
int main()
{

    myFunc(1,2, sum);
    return 0;
}

4、作为函数返回值

double (*fp)(int) myFunc(char* s); //函数返回类型为函数指针

以上写法是错误的!

正确的写法是

int (*myFunction(char* s))(int);

解释:

  • myFunction是函数名
  • 参数是char* s
  • 前后两个int说明该函数的返回类型是“参数为int,返回类型为int的函数指针”
int* (*myFunction(const char* s, int* (*fp)(void) ))(void) {
    cout << s <<endl;
    return fp;
}
int* func(void) {
    cout << "I'm the returned function";
    return NULL;
}
int* (*returnFp)(void);
int main()
{
    returnFp =myFunction("So complicated.",func);
    returnFp();
    return 0;
}

输出:

So complicated.
I'm the returned function

但实际上 不建议 这样写!
如果用typedef代码会简单很多!

typedef int (*fp)(int);
fp myFunction(char* s); // function returning function pointer

5、函数指针数组

//以下四个函数的参数列表是等价的
const double* f1(const double arr[], int n);
const double* f2(const double* arr, int n);
const double* f3(const double [], int);
const double* f4(const double*, int);

const double* (*parray[4])(const double*, int)={f1,f2,f3,f4};

parray是一个函数指针数组

const double* f1(const double arr[], int n);
const double* f2(const double* arr, int n);
const double* f3(const double [] , int);
int main()
{
    double arr[3] = {1.1,2.2,3.3};
    const double* (*parray[3])(const double*, int) = { f1,f2,f3 };
    cout << "Address0 : " << parray[0](arr, 0) << " — " <<  *(parray[0](arr, 0)) << endl;
    cout << "Address1 : " << parray[1](arr, 0) << " — " << *(parray[1](arr, 0)) << endl;
    cout << "Address2 : " << parray[2](arr, 0) << " — " << *(parray[2](arr, 0)) << endl;
    return 0;
}
const double* f1(const double arr[], int n) {
    return arr;
}
const double* f2(const double arr[], int n) {
    return ++arr;
}
const double* f3(const double arr[], int n) {
    return ++(++arr);
}

输出:

Address0 : 0055FB94 — 1.1
Address1 : 0055FB9C — 2.2
Address2 : 0055FBA4 — 3.3

使用typedef

typedef const double* (*PF)(const double [], int);  // 将pf定义为一个类型名称
PF parray[3] = { f1,f2,f3 };

6、总结

适当使用 typedef 会让代码 简洁 且 可读性更高

参考:
Microsoft C++文档—函数指针
C++函数指针

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值