函数指针声明必须包含正确的返回值类型和输入类型
如函数原型:
int pam(int );
正确的函数指针应该为:
int (*p)(int);
如果写为
double (*p)(int);肯定是错误的。
当然这里指的是简单的函数
如果函数更加复杂如下:
const int *f1(const double *,int)
首先这个函数原型是一个返回一个const int 指针的函数,其次
他需要接受2个参数一个是const double类型的指针,当数组作为
形参的时候传递的实际上是地址而不是实际的数据,第二参数就是
一个整形。
那么关于这样的函数我们怎么声明一个函数指针呢?如下:
const int* (*p)(const double *,int)
首先这是一个指针p并且为一个函数指针他带入两个形参,其次
他的返回值为一个指针这个指针是const int类型的。
如果要建立一个数组,其中包含3个这样的函数指针该如何呢?
const int* (*p[3])(const double *,int)
类似的我们经常使用*argv[4],他就是一个包含3个指针的数组
只是这种指针是函数指针。
我们知道数组的名字就是数组内存空间的首地址,那么。这里
p就是这样一个指针,他是指向函数指针的指针,当然是第一个
p+1呢当然也是也是一个指向函数指针的指针,当然是第二个元素。
当然如果调用我们可以
const int *a = (*p[1])(darray,10)
或者
const int *a = p[1](darray,10)
这两者来自不同的认为,一个认为p[1]既然是一个函数地址那么要
取其函数就是*p[1],另外一个认为p[1]为函数的地址而函数名字本生
就是地址,那么这麽调用也没有问题,如此C/C++折中后认为他们都
正确,个人认为(*p[1])(darray,10)更加明了
如果直接取值即可以
const int a = *((*p[1])(darray,10))
或者
const int a = *(p[1](darray,10))
更加复杂一些
const int* (*(*pt)[3])(const double *,int) = &p;
首先pt是一个指针,然后合[]进行结合,说明他有3个元素的数组
而这个素组包含的3个元素是**pt的类型,并且他是函数指针,
最后这个pt指针指向了&p
const int* (*p[3])(const double *,int)
首先p是一个指针,并且是指向数组的第一个元素,并且数组中每一个元素都是
函数指针。
那么&p就是一个指向 函数指针的指针 的指针,听起来很复杂。确实也比较复杂。
那么
const int* (*(*pt)[3])(const double *,int)
也是一个指向 函数指针的指针 的指针。
调用为
const int *a = (*(*pt)[1])(darray,10)
或者
const int *a = (*pt)[1](darray,10)
const int a = *((*(*pt)[1])(darray,10))
或者
const int a =*((*pt)[1](darray,10))
如同二维素组的指针
int (*p)[3] [3]代表了有3个元素,及(*p)[0],(*p)[1],(*p)[2],当然他也等价
为*p+0,*p+1,*p+2的3个元素地址,第二行为*(p+1)+0,*(p+1)+1,*(p+1)+2
(*(p+1))[0],(*(p+1))[1],(*(p+1))[2]
这里形式和我们这里的形式
const int* (*(*pt)[3])(const double *,int) = &p;
有点相识,
那么引申开来,&p或者pt就是整个函数指针素组的地址,他包含了3个元素,
如
(*pt)[0]或者*pt+0
他就是一个函数指针形参为(const double *,int)
这里注意下虽然p和&p有同样的地址,但是他们步长并不一样。
接下来看一下相对比较复杂的函数指针的列子
<ptad<<endl; pointer="" to="" function="" array="" address<pt+0<<endl; ="" pointer="" to="" function="" array="" number="" 1<pt+1<<endl; ="" pointer="" to="" function="" array="" number="" 2<datac<<endl;
<step;i++)
<endl;
<step;i++)
<endl;
<count<<endl;
<step;i++)
<endl;
<endl;
<count<<endl;
1 /*************************************************************************
2 > File Name: functionp.cpp
3 > Author: gaopeng
4 > Mail: gaopp_200217@163.com
5 > Created Time: Thu 26 May 2016 05:42:20 PM CST
6 ************************************************************************/
7
8 #include
9 #include
10 using namespace std;
11
12 const int* add(const int *data,int step);
13 const int* mul(const int *data,int step);
14
15 int getdata (int *data,int step);
16
17
18
19 int main(void)
20 {
21 int datac=0;
22 int data[5];
23 const int* (*pt[2])(const int *,int); //pt[2] is function pointer array have 2 number
24 const int* (*(*ptad)[2])(const int *,int); //ptad is function array adress step is 2
25 getdata(data,5);
26 pt[0]=add; //function pointer
27 pt[1]=mul; //function pointer
28 ptad=&pt;
29 cout<<"function array address is "<<ptad<<endl; //pointer to function pointer array address
30 cout<<"function 1 address is "<<pt+0<<endl; //pointer to function pointer array number 1
31 cout<<"function 2 address is "<<pt+1<<endl; //pointer to function pointer array number 2
32 for(int i=0;i<2;i++)
33 {
34
35 datac += *((*(*ptad+i))(data,5)); //*ptad+i is pointer to add address and mul adress,*(*ptad+i) is add and mul
36 }
37 cout<<" mul+add "<<datac<<endl;
38 }
39
40
41 int getdata (int *data,int step)
42 {
43
44 for(int i=0;i<step;i++)
45 {
46 if(!(cin >> data[i]))
47 {
48
49 cin.clear();
50 while(cin.get()!= '\n')
51 {
52 continue;
53 }
54 cout<< "please input int data"<<endl;
55 exit(1);
56 }
57 }
58 return 0;
59 }
60
61
62 const int* add(const int *data,int step)
63 {
64
65 static int count=0;
66 for(int i=0;i<step;i++)
67 {
68 //cout <<"add:" <<*(data+i) <<endl;
69 count += *(data+i);
70 //cout<<count<<endl;
71 }
72 return &count;
73 }
74
75 const int* mul(const int *data,int step)
76 {
77
78 static int count=1;
79 for(int i=0;i<step;i++)
80 {
81
82 if(*(data+i) == 0)
83 {
84
85 cout<<"Cannot data into 0"<<endl;
86 exit(0);
87 }
88
89 //cout <<"mul:"<< *(data+i) <<endl;
90 count *= *(data+i);
91 //cout<<count<<endl;
92 }
93 return &count;
94 }
其实整个例子很简单,就是计算几个输入值的和与乘的和,但是为了展示
const int* (*(*ptad)[2])(const int *,int);
这样一种ptad指向一个 函数指针数组的指针,所以这样写了。
实际数组的名字也是指针那么我们可以理解为
ptad指向一个 指向指针的指针 的指针
注意到结合性(*(*ptad)[2])(const int *,int)
不要写成*(*ptad)[2](const int *,int)
很明显()的结合性强于*
那么(*ptad)[2]先与(const int *,int)结合在结合*
最后看看程序的输出
1
2
3
4
5
function array address is 0x7ffeede71e60
function 1 address is 0x7ffeede71e60
function 2 address is 0x7ffeede71e68
mul+add 135
可以看到ptad和pt+0的地址一样但是他们的含义不同ptad的步长为2是函数指针数组的地址,而pt+0 是第一个函数的指针地址
</count<<endl;
</endl;
</endl;
</step;i++)
</count<<endl;
</endl;
</step;i++)
</endl;
</step;i++)
</datac<<endl;
</pt+1<</pt+0<</ptad<
函数指针复杂的例子
2021-10-09 03:46:29