首先看下面两个声明代表什么意思?
double* (*(*pf)[2])(double*,int);
double* (*pa[2])(double*,int);
要搞清楚这两个式子,则先要清楚
- 指向指针的指针
- 指针数组与指向数组的指针
- 函数指针
指向指针的指针
指针的指针特殊点在于指向的是一个指针而已,解引用它得到指向的指针的地址,再解引用便可得到变量的值
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);