函数指针

一、现在有一个函数func(),要实现将一个函数作为参数传进这个函数中。为此,必须要完成以下操作:

1、获取函数的地址,使用函数名即可

2、声明一个函数指针,声明应该像函数原型那样指出有关函数的信息。

double pam(int);//prototype
double (*pf)(int);

pam是函数,因此(*pf)也是函数,所以pf是函数指针。 

3、使用函数指针来调用函数

(*pf)扮演的角色与函数名相同,因此使用(*pf)时,只需将它看做函数名即可。

double pam(int);
double (*pf)(int);
pf = pam;
double x = pam(4);
double y = (*pf)(5);

实际上,C++也允许像使用函数名那样使用pf:

double y = pf(5);

二、深入探讨函数指针

下面是一些函数原型,它们的特征标和返回类型相同:

const double* f1(const double ar[], int n);
const double* f2(const double [], int);
const double* f3(const double *,int);

这些函数的特征标看似不同,但实际相同。首先,在函数原型中,参数列表const double ar[]与const double * ar的含义完全。其次,在函数原型中,可以省略标识符。因此,const double ar[]可简化为const double []。因此,上述所有函数特征标的含义完全都相同。另一方面,函数定义必须提供标识符,因此需要使用const double ar[]或const double *ar。

声明一个指针:

const double* (*p1)(const double *, int) = f1;;

 这里声明的时候使用自动类型推断:

auto p2 = f2;

看下面的语句:

cout<<(*p1)(av, 3)<<" :"<<*(*p1)(av, 3)<<endl;
cout<<p2(av, 3)<<" :"<<*p2(av, 3)<<endl;

为查看存处在这些地址的实际值,需要用运算符*应用于这些地址。

三、函数指针数组

还是上面的代码,因为需要使用三个函数,有一个函数指针数组就非常方便:

const double * (*pa[3])(const double *, int) = {f1, f2, f3};

运算符[ ]的优先级高于*,因此*pa[3]表明pa是一个包含三个指针的数组。特征标为const double *, int, 返回值为const double *的函数。

这里能否使用auto呢?不能。自动类型转换只能用于单值初始化,而不能用于初始化列表。但声明数组pa后,声明同样的类型的数组就简单了:

auto pb = pa;

pa[i]和pb[i]都表示数组中的指针,如果要调用它们,一下两种方法都可以:

double x = pa[0](av, 3);
double y = (*pb[1])(av, 3);

还可以创建指向整个数组的指针。由于数组名pa是指向函数指针的指针,因此指向数组的指针将是这样的指针,即它指向指针的指针,但由于可以使用单个值对其进行初始化,因此可以使用auto:

auto pc = &pa;

如果要自己声明,该怎么办呢?这种声明类型与pa的声明,但由于增加了一层间接,因此需要在一个地方添加一个*。具体的说,如果这个指针名为pd,则需要指出它是一个指针,而不是数组。这意味着核心部分应该是(*pd)[3],其中括号让标识符pd先与*结合:

const double *(*(*pd)[3])(const double *, int) = &pa;

需要调用函数,须认识到这一点:既然pd指向数组,那么*pd就是数组,而(*pd)[i]是数组中的元素,即函数指针。因此,较简单的调用方法是:

(*pd)[i](av, 3)

复杂的是:

(*(*pd)[i])(av, 3);

注意:从数字上说,pa和&pa的值相同,但它们的类型不同。一种差别是:pa + 1为数组中下一个元素的地址,而&pa + 1为数组pa后面一个12字节内存块的地址。另一个差别是:要得到第一个元素的值,只需要对pa解除引用一次,但需要对&pa解除引用两次:

**&pa == *pa == pa[0];

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值