C 中的指標 二 函式指標

2021-04-12 20:31:13 字數 3047 閱讀 4352

原帖及討論:http://bbs.bc-cn.net/dispbbs.asp?boardid=56&id=92806

先說一下c式的函式

指標。這種函式

指標的應用十分廣泛。

對於任何函式 void print(string s),它的指標這樣定義:

void (*pfun)(string) = null;

pfun= &print;

或者 pfun = print;兩種寫法沒有區別。

pfun是指標變數名。可以指向任何只帶乙個string引數,返回void的函式。這裡讓它指向print()函式。

以後呼叫它的時候直接寫

if (pfun)

pfun("hello world");

c++編譯器會通過pfun找到print函式,然後call  print("hello world");

乙個簡單應用是可以作選單操作。例如在文字模式下的介面,讓使用者選擇如下操作:

"0.print, 1.copy, 2.delete, 3. quit, 4.help"

那麼可以寫5個函式:

void print();

void copy();

void delete();

void quit();

void help();

然後用乙個函式

指標陣列把他們存在一起:

void (*p)() = ;

然後根據使用者入0,1,2,3,4來直接叫函式

cin >> index;

p[index]();

在windows環境下編譯這種函式

指標被認為是用c/c++呼叫規則(c/c++ calling convention)。就是呼叫函式caller清理函式呼叫時生成的stack。另一種規則叫標準呼叫規則(standard calling convention)。由被叫函式callee清理自己的stack。二者一般情況下區別不大,但standard calling convention更合理,因為這樣使函式size變小了一點。

實際上寫c/c++

函式指標的時候省略了 __cdecl 字首。 應該寫成void (__decel *p)();

而標準規範用 __stdcall字首。 也可以用巨集callback,這也就是著名的**函式了。

使用callback的另乙個好處就是呼叫函式(caller)不需要具體關心被叫函式(callee)是什麼而直接呼叫。例如我們要寫乙個排序函式。可以用各種不同演算法。如冒泡法。

void callback bubblesort(int *pstart, int *pend);

也可以用quick sort

void callback quicksort(int *pstart, int *pend);

那麼呼叫方只需要定義乙個指向這種格式的函式

指標:void (callback *p)(int*, int*),然後讓p指向想用的函式就可以了。

這裡只對int型別排序,實際上這種排序函式可以再叫乙個callback函式來決定排序規則。以使演算法可以應用到各種不同型別的變數以及不同的排序規則中。在各演算法書上都有介紹。如果大家有興趣,我可以寫一下這個排序函式。

另乙個典型的例子是mfc中timer使用的callback函式,每當timer exprie的時候會去叫這個函式,根據返回值決定下乙個動作。

c++中的函式

指標與c的不同

class c

這裡指向print的指標不是bool *p(),而是bool (c::*p)();

呼叫這個函式的時候這樣寫:

c c, *pc=&c;

bool (c::*p)() = &c::test;

c.*p();

或者 pc->*p();

賦值那行bool (c::*p)() = &c::test;在vs2003裡右邊可以省去 c::,到了vs2005語法更嚴格了,被禁止了。這裡的成員函式

指針對非靜態函式有效。靜態函式不依賴於任何object,它的表示方法和c的一樣。

對於非靜態成員函式的指標的繼承關係是這樣的:upcast合法,downcast不合法。這樣的到的指標永遠是安全的。

非靜態成員函式

指標在實際程式中的應用很多。乙個典型的例子是用來寫state machine(狀態機器?)。例如程式在控制乙個機械人的初始化階段。整個初始化需要三個函式:1。初始化機械人的身子,2。初始化機器的左手,3。初始化機械人的右手。這樣我們在state machine中用兩個成員函式

指標分別指向當前的狀態和下乙個狀態 bool (cstatemachine::*m_pcurrentstate), bool (cstatemachine::*m_pnextstate)。。

一開始永遠叫start()

cstatemachine::cstatemachine

然後在每乙個state裡面管理狀態變化:

bool cstatemachine::start()

bool cstatemachine::initializelefthand()

bool cstatemachine::initializerighthand()

這樣很清晰的標誌了整個初始化的過程。當然這個過程也可以用很土的程式實現,設乙個flag,然後把flag於函式一一對應。但那樣作出來的程式不易懂,同時增加新狀態的時候不好維護。

對於cstatemachine的核心部份可以這樣控制:對於任何一步操作,如果函式返回true表示成功,執行下一步

(this->*(m_pcurrentstate = m_pnextstate))()。如果失敗則報錯,同時讓使用者選擇重試(retry)還是放棄(abort)還是忽略(ignor)。

如果abort則結束statemachine,

如果retry則再次叫當前函式this->*m_pcurrentstate();

如果ignor則忽略當前錯誤繼續下一步。this->*(m_pcurrentstate = m_pnextstate)();

當沒有下乙個狀態的時候statemachine結束。 (m_pnextstate == null)

這是標準工業中的用法,大家不妨看一看,寫成乙個標準的class。這將是個很有用的練習。

C 中的函式指標

函式指標也叫指向函式的指標,它是為了提高函式的通用性而引入的。比較傳統的方法是在函式中增加引數,通過增加的引數來判斷到底要用什麼函式,這樣的缺點是靈活性差,為了支援多種方法要在函式中要寫很多分支判斷語句。比如,你要計算乙個函式值 如sin x,log10 x 的平方,按照傳統的方法你可以這樣寫這個函...

C 中的函式指標

在c 中,指標變數可以指向普通變數 字串和陣列等,同時也可以指向函式,因為乙個函式在編譯時被分配乙個入口位址,這個入口位址即為該函式的指標。所以,可以用指標變數指向函式,然後通過該指標變數呼叫此函式。在c 中,函式的名稱就代表了一般定義形式為 資料型別表示符 指標變數名 例如 int p 程式示例 ...

C語言指標(函式指標陣列,二級指標)

int p num char int,int int p num int a 函式指標陣列指標和前面的陣列指標其實沒有太大區別。然後今天主要理一下函式指標陣列和二級指標。函式指標陣列中,存放的一定要是相同返回值型別,以及相同引數列表的函式指標,這樣陣列可以通過下標來呼叫不同的函式,省去了使用大量的判...