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++程式設計中使用的廣泛性,而對於一些初級程式設計者來說對函式指標的使用或許有些迷惑,而一旦在適當的時候使用了函式指標,會使程式碼簡潔有力。本篇介紹的是函式指標的基礎部分,函式指標複雜的應用將在下一篇介紹。
一 指向普通函式的指標
先來看一個函式:
- int Sum(int a, int b)
- {
- return a + b;
- }
這個函式,呼叫方式可以如
Sum(1, 2);
若要表示函式的指標,可以用&Sum,也可以將Sum前邊的地址操作符&去掉,對於普通函式,地址操作符&是可選的
下面介紹函式指標變數和函式指標型別:
1. 函式指標變數
- int (*FnName)(int, int); // 宣告一個函式指標,可以將FnName理解為新定義的變數
- FnName = ∑ // 將Sum函式的地址賦給它
- (*FnName)(3, 5); // 和呼叫Sum(3, 5)的效果是一樣的
第1行聲明瞭一個函式指標變數,如果有疑問,可以將FnName理解為一個新定義的變數。函式指標變數的宣告格式:
返回型別(*函式指標變數)(引數列表);
第2行將Sum函式指標賦給它,注意,只有兩個函式指標引數型別,返回值型別完全相同才可以賦值,注意修飾符const,&等不同也會導致賦值失敗。
第3行是呼叫,呼叫格式:
(*函式指標變數)(實參列表);
2. 函式指標型別
前面介紹了函式指標變數的宣告,那麼函式指標型別如何宣告呢?
在函式指標宣告前面加個typedef就成了函式指標型別定義。- typedefint (*FnType)(int, int); // 宣告一個函式指標型別
- FnType fb = ∑ // 定義一個FnType型別的變數,並賦值
- (*fb)(3, 5); // 函式呼叫
第1行宣告函式指標的型別,FnType便是新宣告的型別,它是函式指標的型別。
第2行定義一個FnType型別的變數,並將Sum函式地址賦值給它。
第3行是函式呼叫。
前面已經瞭解了函式指標的變數和型別,看下面的程式碼加深下理解:- int Sum(int a, int b)
- {
- return a + b;
- }
- typedefint (*FnType)(int, int);
- int Fun1(FnType ft, int x, int y)
- {
- return (*ft)(x, y);
- }
- // 函式指標可以定義在引數列表中,在函式體內使用
- int Fun2(int (*fn)(int, int), int x, int y)
- {
- return (*fn)(x, y);
- }
- int main()
- {
- cout << Fun1(&Sum, 2, 3) << " "; // 輸出 5
- cout << Fun2(&Sum, 3, 4) << "\n"; // 輸出 7
- return 0;
- }
關於普通函式指標的學習就到這裡吧,簡單吧:),下面就來學習類的成員函式的指標。
二 指向類成員函式的指標
先看下面這個類:- class Num
- {
- public:
- Num(){n_ = 0;}
- void Inc(int n);
- void Dec(int n);
- staticint Sub(int a, int b);
- private:
- long n_;
- };
這個類中有普通成員函式,也有靜態成員函式,無論哪種函式,函式指標表示方式都是:
&類名::函式名
如Num類三個成員函式的指標分別是:
&Num::Inc;
&Num::Dec;
&Num::Sub;1. 指向普通成員函式的指標
宣告一個指向類成員函式的指標時需要用到::*符號,左邊是類名,右邊是成員函式指標名:
返回型別 類名::*成員函式指標(引數列表);
呼叫的時候要用到.*或->*,左邊是類物件的引用或指標,右邊是成員函式指標:
(物件名.* 成員函式指標)(實參);
或
(物件指標->* 成員函式指標)(實參);
程式碼示例:
- int main()
- {
- Num obj;
- void (Num::*mf)(int); // 宣告指向成員函式的指標 mf
- mf = &Num::Inc; // 賦值
- (obj.*mf)(1); // 呼叫
- // 成員函式的指標型別
- typedefvoid (Num::*mt)(int);
- mt fn = &Num::Dec;
- (obj.*fn)(2);
- return 0;
- }
注意上面,Sub是靜態成員函式,其指標宣告跟非靜態成員函式不一樣,下面來看靜態成員函式的指標。
2. 指向靜態函式的指標- int (*smf)(int a, int b); // 注意寫法
- smf = &Num::Sub;
- cout << (*smf)(6, 7); // 呼叫方式跟上一節講的普通函式呼叫方式一樣
可以看到,靜態成員函式指標變數、型別宣告與普通函式一致。
3. 指向虛擬函式的指標
先上程式碼:
- class Base{
- public:
- virtualvoid F() const
- {
- cout << "I am the Base\n";
- }
- typedefvoid (Base::*FnPtr)() const;
- };
- class Derived : public Base{
- public:
- virtualvoid F() const
- {
- cout << "I am the Derived\n";
- }
- };
- int main()
- {
- Base::FnPtr fp = &Base::F;
- Base base;
- (base.*fp)();
- Derived derived;
- (derived.*fp)();
- return 0;
- }
輸出結果:
I am theBase
I am theDerived
可見,虛擬函式的指標呼叫結果跟直接呼叫虛擬函式效果一樣,虛擬函式的指標指向的函式地址是物件動態繫結的函式地址。接下來,介紹一下函式指標在回撥函式的應用
模板類,該類擁有2個成員,一個是物件指標,一個是成員函式,成員函式必須無參,無返回值。
- struct CallbackAction {
- virtualvoid Execute() = 0;
- virtual ~CallbackAction() {}
-
相關推薦
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