C++ 函数指针探幽

首先看下面两个声明代表什么意思?

double* (*(*pf)[2])(double*,int);
double* (*pa[2])(double*,int);

要搞清楚这两个式子,则先要清楚

  1. 指向指针的指针
  2. 指针数组与指向数组的指针
  3. 函数指针

指向指针的指针

在这里插入图片描述
指针的指针特殊点在于指向的是一个指针而已,解引用它得到指向的指针的地址,再解引用便可得到变量的值

int i = 10;
int *p = &i;
int **pp = &p;
std::cout<<pp<<" "<<*pp<<" "<<**pp<<std::endl;

输出:
0000001E45AFF8D8 0000001E45AFF8B4 10

指针数组与指向数组的指针

指针数组表示数组里面的每一个元素都是一个指针;而指向数组的指针表示它指向一个数组的首地址

太绕,具体说明下

//我声明的数组
int arr[2][2] = {{1,2},{3,4}};
//指针数组,[] 比 * 优先级高,这是一个含有两个元素的数组,并且这两个元素都是指针
int *p[2] = {arr[0],arr[1]}; // 这两个指针分别指向arr数字第一行和第二行首地址,也可以指向其他数组的地址
//可以当数组用了
std::cout<<p[0][0]<<" "<<p[1][0]<<std::endl; 

//指向数组的指针
int (*pr)[2] = arr;
std::cout<<pr[0][0]<<" "<<pr[1][0]<<std::endl;
//等效
std::cout<<(*pr)[0]<<" "<<(*(pr+1))[0]<<std::endl;

一定要注意里面的区别
在这里插入图片描述

函数指针

顾明思义,这个指针指向函数,声明和指向的函数必须相同的参数和返回值

//这是函数声明
double* fun(double* dis, int price);
//函数指针,参数名可省略
double* (*pfun)(double*, int);

到此,我们先回头看

double* (*pa[2])(double*,int);

明显,这是一个包含两个函数指针的数组,指向的函数原型为

double* fun(double* dis, int price);

so, 我们可以让这两个指针分别指向两个不同的函数;

//用 typedef 修饰,则可以直接用pa声明此类指针数组
typedef double* (*pa[2])(double*,int);

double* f1(double* discount, int price)
{
    std::cout<< "f1(): "<< price*(*discount) << std::endl;
    return 0;
}

double* f2(double* discount, int price)
{
    std::cout<< "f2(): "<< price*(1.0 - *discount) << std::endl;
    return 0;
}
pa p = {f1,f2};
double dis = 0.6;
(*p)(&dis,10);
//p[0](&dis,10);
//(*(p+1))(&dis,10);
p[1](&dis,10);

继续

double* (*(*pf)[2])(double*,int);

(pf)[2] 表示这是一个指向包含2个元素的数组的指针,而 ((*pf)[2]) 则表示指向 (pf)[2] 的指针,指针又是一个返回值为 double 的函数指针。

举例来看

typedef double* (*(*pf)[2])(double*,int);
// 接上面的例子,p 的pa类型的函数指针,p1 是指向 p 的指针
pf p1 = &p;
// 解引用 p1 就得到的指向的指针地址(p的地址)
(*p1)[0](&dis,10);
//(*p1)[1](&dis,10);
(*((*p1)+1))(&dis,10);
//错误,你明白为什么了吗?
//(*(*(p1+1)))(&dis,10);

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值