宣告函式指標並實現回撥 (轉)
員常常需要實現回撥。本文將討論函式指標的基本原則並說明如何使用函式指標實現回撥。注意這裡針對的是普通的函式,不包括完全依賴於不同語法和語義規則的類成員函式(類成員指標將在另文中討論)。
宣告函式指標
回撥函式是一個程式設計師不能顯式的函式;透過將回撥函式的地址傳給呼叫者從而實現呼叫。要實現回撥,必須首先定義函式指標。儘管定義的語法有點不可思議,但如果你熟悉函式宣告的一般方法,便會發現函式指標的宣告與函式宣告非常類似。請看下面的例子:
void f();// 函式原型
上面的語句宣告瞭一個函式,沒有輸入引數並返回void。那麼函式指標的宣告方法如下:
void (*) ();
讓我們來分析一下,左邊圓括弧中的星號是函式指標宣告的關鍵。另外兩個元素是函式的返回型別(void)和由邊圓括弧中的入口引數(本例中引數是空)。注意本例中還沒有建立指標變數-只是宣告瞭變數型別。目前可以用這個變數型別來建立型別定義名及用sizeof獲得函式指標的大小:
// 獲得函式指標的大小
unsigned psize = sizeof (void (*) ());
// 為函式指標宣告型別定義
typedef void (*pfv) ();
pfv是一個函式指標,它指向的函式沒有輸入引數,返回類行為void。使用這個型別定義名可以隱藏複雜的函式指標語法。
指標變數應該有一個變數名:
void (*p) (); //p是指向某函式的指標
p是指向某函式的指標,該函式無輸入引數,返回值的型別為void。左邊圓括弧裡星號後的就是指標變數名。有了指標變數便可以賦值,值的內容是署名匹配的函式名和返回型別。例如:
void func()
{
/* do something */
}
p = func;
p的賦值可以不同,但一定要是函式的地址,並且署名和返回型別相同。
傳遞迴調函式的地址給呼叫者
現在可以將p傳遞給另一個函式(呼叫者)- caller(),它將呼叫p指向的函式,而此函式名是未知的:
void caller(void(*ptr)())
{
ptr(); /* 呼叫ptr指向的函式 */
}
void func();
int main()
{
p = func;
caller(p); /* 傳遞函式地址到呼叫者 */
}
如果賦了不同的值給p(不同函式地址),那麼呼叫者將呼叫不同地址的函式。賦值可以發生在執行時,這樣使你能實現動態繫結。
呼叫規範
到目前為止,我們只討論了函式指標及回撥而沒有去注意ANSI C/C++的規範。許多編譯器有幾種呼叫規範。如在Visual C++中,可以在函式型別前加_cdecl,_stdcall或者_pascal來表示其呼叫規範(預設為_cdecl)。C++ Builder也支援_fastcall呼叫規範。呼叫規範影響編譯器產生的給定函式名,引數傳遞的順序(從右到左或從左到右),堆疊清理責任(呼叫者或者被呼叫者)以及引數傳遞機制(堆疊,暫存器等)。
將呼叫規範看成是函式型別的一部分是很重要的;不能用不相容的呼叫規範將地址賦值給函式指標。例如:
// 被呼叫函式是以int為引數,以int為返回值
__stdcall int callee(int);
// 呼叫函式以函式指標為引數
void caller( __cdecl int(*ptr)(int));
// 在p中企圖被呼叫函式地址的操作
__cdecl int(*p)(int) = callee; // 出錯
指標p和callee()的型別不相容,因為它們有不同的呼叫規範。因此不能將被呼叫者的地址賦值給指標p,儘管兩者有相同的返回值和引數列。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988569/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 函式指標&回撥函式Callback函式指標
- 函式指標之回撥函式和轉移表函式指標
- 回撥函式(c和指標)函式指標
- 【不在混淆的C】指標函式、函式指標、回撥函式指標函式
- C語言函式指標與回撥用函式C語言函式指標
- 宣告與函式、函式指標函式指標
- C語言函式指標與回撥函式使用方法C語言函式指標
- C++定義函式指標,回撥C#C++函式指標C#
- 函式指標的重要用途——回撥函式函式指標
- C語言關於回撥函式和this指標探討C語言函式指標
- 回撥函式快速使用 (轉)函式
- 回撥函式函式
- 詳解C/C++函式指標宣告C++函式指標
- JavaScript 回撥函式JavaScript函式
- JavaScript回撥函式JavaScript函式
- JS—回撥函式JS函式
- 動畫回撥函式動畫函式
- java回撥函式Java函式
- 回撥函式(CallBack)函式
- [JS]回撥函式和回撥地獄JS函式
- 回撥函式,求積函式函式
- 利用指標實現strncmp函式功能指標函式
- 指標函式 和 函式指標指標函式
- 回撥函式 與 函式閉包函式
- 回撥函式的作用函式
- TLS回撥函式(Note)TLS函式
- java 回撥函式示例Java函式
- Python回撥函式Python函式
- android回撥函式Android函式
- 函式回撥(C++)函式C++
- 理解javascript中的回撥函式(callback)【轉】JavaScript函式
- 回撥函式、訊息和事件例程 (轉)函式事件
- 函式指標淺談 (轉)函式指標
- 事實上,回撥函式還不錯!!函式
- JS閉包函式和回撥函式JS函式
- 用 Java 實現回撥例程 (轉)Java
- C++回撥函式 用法C++函式
- 回撥函式的理解(一)函式