函式指標複雜的例子

gaopengtttt發表於2016-05-31
函式指標宣告必須包含正確的返回值型別和輸入型別
如函式原型:
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<

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2109957/,如需轉載,請註明出處,否則將追究法律責任。

相關文章