1. 程式人生 > >int * (*ptr)()怎麼理解(指向函式的指標)

int * (*ptr)()怎麼理解(指向函式的指標)

先來分析一下int * (*ptr)()

1.由於小括號的運算級比較高,結合方法又是自左向右,所以先運算(*ptr),表明定義了一個指標ptr
2.接下來再運算最右邊的小括號(),表明是一個函式
3.接下平再運算* (*ptr)(),表明函式的返回值是一個指標
4.那麼int * (*ptr)()表明定義了一個指標變數ptr,它指向一個沒有引數,並且返回值是一個整型指標的函式。
這就叫做指向函式的指標,雖然以前聽人說大多都是在回撥函式中用,但是一直感覺和普通函式每什麼區別,今天看了一個部落格算是多多少收懂了一下,下面的博文有點長,不過如果你看懂了相信收貨一定會不小的(起碼我懂了回撥函式到底是怎麼一回事~~)。

博文原址http://blog.csdn.net/hzyong_c/article/details/7464202

首先,先介紹一下指向函式的指標

函式指標在C/C++程式設計中使用的廣泛性,而對於一些初級程式設計者來說對函式指標的使用或許有些迷惑,而一旦在適當的時候使用了函式指標,會使程式碼簡潔有力。本篇介紹的是函式指標的基礎部分,函式指標複雜的應用將在下一篇介紹。

一  指向普通函式的指標

先來看一個函式:

  1. int Sum(int a, int b)  
  2. {  
  3.   return a + b;  
  4. }  

這個函式,呼叫方式可以如

Sum(1, 2);

若要表示函式的指標,可以用&Sum,也可以將Sum前邊的地址操作符&去掉,對於普通函式,地址操作符&是可選的

下面介紹函式指標變數和函式指標型別: 

1.  函式指標變數

  1. int (*FnName)(intint);           // 宣告一個函式指標,可以將FnName理解為新定義的變數
  2. FnName = ∑             // 將Sum函式的地址賦給它
  3. (*FnName)(3, 5);           // 和呼叫Sum(3, 5)的效果是一樣的

第1行聲明瞭一個函式指標變數,如果有疑問,可以將FnName理解為一個新定義的變數。函式指標變數的宣告格式:

返回型別*函式指標變數)(引數列表);

第2行將Sum函式指標賦給它,注意,只有兩個函式指標引數型別,返回值型別完全相同才可以賦值,注意修飾符const,&等不同也會導致賦值失敗。

第3行是呼叫,呼叫格式:

*函式指標變數)(實參列表);

2.  函式指標型別

前面介紹了函式指標變數的宣告,那麼函式指標型別如何宣告呢?

在函式指標宣告前面加個typedef就成了函式指標型別定義。
  1. typedefint (*FnType)(intint);   // 宣告一個函式指標型別
  2. FnType fb = ∑                   // 定義一個FnType型別的變數,並賦值
  3. (*fb)(3, 5);                        // 函式呼叫

第1行宣告函式指標的型別,FnType便是新宣告的型別,它是函式指標的型別

第2行定義一個FnType型別的變數,並將Sum函式地址賦值給它。

第3行是函式呼叫。 

前面已經瞭解了函式指標的變數和型別,看下面的程式碼加深下理解:
  1. int Sum(int a, int b)  
  2. {  
  3.   return a + b;  
  4. }  
  5. typedefint (*FnType)(intint);  
  6. int Fun1(FnType ft, int x, int y)  
  7. {  
  8.   return (*ft)(x, y);  
  9. }  
  10. // 函式指標可以定義在引數列表中,在函式體內使用
  11. int Fun2(int (*fn)(intint), int x, int y)  
  12. {  
  13.   return (*fn)(x, y);    
  14. }  
  15. int main()  
  16. {  
  17.   cout << Fun1(&Sum, 2, 3) << " ";  // 輸出 5
  18.   cout << Fun2(&Sum, 3, 4) << "\n"// 輸出 7
  19.   return 0;  
  20. }  

關於普通函式指標的學習就到這裡吧,簡單吧:),下面就來學習類的成員函式的指標。 

二 指向類成員函式的指標

先看下面這個類:
  1. class Num  
  2. {  
  3. public:  
  4.   Num(){n_ = 0;}  
  5.   void Inc(int n);  
  6.   void Dec(int n);  
  7.   staticint Sub(int a, int b);  
  8. private:  
  9.   long n_;  
  10. };  

這個類中有普通成員函式,也有靜態成員函式,無論哪種函式,函式指標表示方式都是:

&類名::函式名

如Num類三個成員函式的指標分別是:

&Num::Inc;

&Num::Dec;

&Num::Sub;

1.  指向普通成員函式的指標

 宣告一個指向類成員函式的指標時需要用到::*符號,左邊是類名,右邊是成員函式指標名:

返回型別 類名::*成員函式指標(引數列表);

呼叫的時候要用到.*或->*,左邊是類物件的引用或指標,右邊是成員函式指標:

(物件名.* 成員函式指標)(實參);

(物件指標->* 成員函式指標)(實參); 

程式碼示例:

  1. int main()  
  2. {  
  3.   Num obj;  
  4.   void (Num::*mf)(int);    // 宣告指向成員函式的指標 mf
  5.   mf = &Num::Inc;           // 賦值  
  6.   (obj.*mf)(1);             // 呼叫
  7.   // 成員函式的指標型別
  8.   typedefvoid (Num::*mt)(int);  
  9.   mt fn = &Num::Dec;  
  10.   (obj.*fn)(2);   
  11.   return 0;  
  12. }  

注意上面,Sub靜態成員函式,其指標宣告跟非靜態成員函式不一樣,下面來看靜態成員函式的指標。 

2. 指向靜態函式的指標
  1. int (*smf)(int a, int b); // 注意寫法
  2. smf = &Num::Sub;  
  3. cout << (*smf)(6, 7);        // 呼叫方式跟上一節講的普通函式呼叫方式一樣

可以看到,靜態成員函式指標變數、型別宣告與普通函式一致。 

3. 指向虛擬函式的指標

先上程式碼:

  1. class Base{  
  2. public:  
  3.   virtualvoid F() const
  4.   {  
  5.     cout << "I am the Base\n";  
  6.   }  
  7.   typedefvoid (Base::*FnPtr)() const;  
  8. };  
  9. class Derived : public Base{  
  10. public:  
  11.   virtualvoid F() const
  12.   {  
  13.     cout << "I am the Derived\n";  
  14.   }  
  15. };  
  16. int main()  
  17. {  
  18.   Base::FnPtr fp = &Base::F;  
  19.   Base base;  
  20. (base.*fp)();  
  21.   Derived derived;  
  22.   (derived.*fp)();  
  23.   return 0;  
  24. }  

輸出結果:

I am theBase

I am theDerived

可見,虛擬函式的指標呼叫結果跟直接呼叫虛擬函式效果一樣,虛擬函式的指標指向的函式地址是物件動態繫結的函式地址。

接下來,介紹一下函式指標在回撥函式的應用

模板類,該類擁有2個成員,一個是物件指標,一個是成員函式,成員函式必須無參,無返回值。

  1. struct CallbackAction {  
  2.   virtualvoid Execute() = 0;  
  3.   virtual ~CallbackAction() {}  
  4. 相關推薦

    int * (*ptr)()怎麼理解指向函式指標

    先來分析一下int * (*ptr)() 1.由於小括號的運算級比較高,結合方法又是自左向右,所以先運算(*ptr),表明定義了一個指標ptr 2.接下來再運算最右邊的小括號(),表明是一個函式 3.接下平再運算* (*ptr)(),表明函式的返回值是一個指標 4.那麼

    函式指標指向函式指標指標函式的區別

    函式指標和指標函式的區別: 一、【函式指標】 在程式執行中,函式程式碼是程式的演算法指令部分,它們和陣列一樣也佔用儲存空間,都有相應的地址。可以使用指標變數指向陣列的首地址,也可以使用指標變數指向函式程式碼的首地址,指向函式程式碼首地址的指標變數稱為函式指標。 1、函式指標定義 函式型別(*

    指向陣列的指標二維指標

    char (*a)[N];//指向陣列的指標      a = (char (*)[N])malloc(sizeof(char) * N * m);   printf("%

    簡單理解指標陣列 陣列指標 函式指標 函式指標陣列 指向函式指標陣列的指標

    簡單理解—指標陣列 陣列指標 函式指標 函式指標陣列 指向函式指標陣列的指標 指標陣列 指標陣列,顧名思義是”指標的陣列”,首先這個變數是一個陣列,其次,”指標”修飾這個陣列,意思是說這個陣列的所有元素都是指標型別,在32位系統中,指標佔四個位元組。

    排序演算法1——圖解氣泡排序及其實現三種方法,基於模板及函式指標

    排序演算法1——圖解氣泡排序及其實現(三種方法,基於模板及函式指標) 排序演算法2——圖解簡單選擇排序及其實現 排序演算法3——圖解直接插入排序以及折半(二分)插入排序及其實現 排序演算法4——圖解希爾排序及其實現 排序演算法5——圖解堆排序及其實現 排序演算法6——圖解歸併排序及其遞迴與非

    單鏈表排序函式指標

    問題描述: 使用者輸入資料,構成單鏈表,然後對單鏈表進行排序,能夠隨意切換排序的方法(列入升序降序)。 PS: 要隨意切換排序的方法,那麼使用函式指標作為引數傳入到排序函式中,那麼函式指標指向的函式就可以方便的制定排序規則了。 參考程式碼: #define _CRT_SE

    c++ typedef 函式指標詳細說明包含類函式指標

    http://blog.csdn.net/future200x/article/details/5350134 一個函式在編譯時被分配一個入口地址,將這個入口地址稱為函式的指標,可以用一個指標變數指向該函式指標,然後通過該變數來呼叫函式。 有關說明: 1、

    詳解C++中的純虛擬函式虛擬函式區別&多型性 以及理解

    #include <iostream> #include <cstdio> using namespace std; class A { public:     void foo()     {         printf("1\n");    

    深入理解指標陣列 ,陣列指標函式指標函式指標陣列 ,指向函式指標陣列的指標

    /指標陣列 示例:char *a[4] 理解:定義了一個數組,而它的每個元素的型別是一個指向字元/字串的指標。 元素表示:char *a[i]   char *(a[i])是一樣的,因為[]優先順序高

    求兩個數的最大值函式指標變數呼叫函式

    #include<stdio.h> int max(int a,int b) {  if(a>b)  return a;  else  return b; } int main() {     int x,y,z;     scanf("%d%d",&

    理解 指標陣列 陣列指標 函式指標 函式指標陣列 指向函式指標陣列的指標

    一、指標陣列與陣列指標先看兩行程式碼,猜猜哪個是陣列,哪個是指標int *p[5];int (*p)[5];有沒有很簡單,但是有很多初學者很是分不清楚;第一個是指標陣列,第二個是陣列指標。且看小僧給大家捋一捋,首先要明白符號優先順序問題,“[ ]”的優先順序高於“*”,所

    <C++學習二十>C++中函式過載的理解未完待續

    摘要: 本篇部落格僅作為筆記,如有侵權,請聯絡,立即刪除(網上找部落格學習,然後手記筆記,因紙質筆記不便儲存,所以儲存到網路筆記)。   我們平時寫程式碼中會用到幾個函式但是他們的實現功能相同,但是有些細節卻不同。例如:交換兩個數的其中包括(int,float,char,double)這些型別。這C語言中我

    C++:檔案讀寫設定及理解open函式的相關屬性設定

    在看C++程式設計思想中,每個練習基本都是使用ofstream,ifstream,fstream,以前粗略知道其用法和含義,在看了幾位大牛的博文後,進行整理和總結: 這裡主要是討論fstream的內容: #include <fstream>ofs

    指標與陣列的關係,指標運算,指向指標指標二維指標

    #include<iostream> using namespace std; int main() { int a[5] = {0,1,2,3,4}; int *p = a; cout << a[1] << endl &

    連結串列中 指向 節點結構體指標指標二重指標原題目為pta上查詢倒數k個位置上的數字

    #include<stdio.h> #include<stdlib.h> typedef struct list{ int num; struct list *next; }List ,*LIST; LIST createlist(LIST *L,

    閱讀理解2000年統考

    erp ssa ted japan market stat some hang 屬性 A history of long and effortless(毫不費力的,容易的) success can be a dreadful(可怕的) handicap(障礙), but,

    談談對事件的理解持續更新中

    use 通過 行為 tlist 理解 scrip 創建 可能 有時 談談對事件的理解: 從前有一家人,我們稱為window家。window他其中有一個兒子叫事件。 -------------------------------------------------------

    指標函式 AND 函式指標 AND 函式指標陣列 AND 指向函式指標陣列的指標

    指標函式 形如“指標陣列”,“指標函式”是一個“函式”,函式的返回型別是指標。 定義 型別識別符號 *函式名(引數表) char *reverse(char *left, char *right); reverse是一個函式,它的返回型別是一個字元

    QQ機器人思路理解C++、CQ

           近期看著教程寫了一下基於C++、CQ下的qq機器人,就是在CQ的主框架上來實現qq的自動檢索並回復的功能。就是這樣已經把主框架都給出來的前提下,依然還是困難重重。        首先,qq機器人利用

    HDOJ-1398 Square Coins函式/DP

    題目描述 Square Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1