C/C++回調(diào)函數(shù)--C作者

原文地址: http://www.cnblogs.com/chenyuming507950417/archive/2012/01/02/2310114.html

今天討論下C/C++中的回調(diào)函數(shù)沦疾。

在理解“回調(diào)函數(shù)”之前围来,首先討論下函數(shù)指針的概念硼一。

函數(shù)指針

(1)概念:指針是一個(gè)變量兢卵,是用來(lái)指向內(nèi)存地址的。一個(gè)程序運(yùn)行時(shí)价认,所有和運(yùn)行相關(guān)的物件都是需要加載到內(nèi)存中,這就決定了程序運(yùn)行時(shí)的任何物件都可以用指針來(lái)指向它。函數(shù)是存放在內(nèi)存代碼區(qū)域內(nèi)的癣疟,它們同樣有地址,因此同樣可以用指針來(lái)存取函數(shù)潮酒,把這種指向函數(shù)入口地址的指針?lè)Q為函數(shù)指針睛挚。

(2)先來(lái)看一個(gè)Hello World程序:

int main(int argc,char* argv[])
{
    printf("Hello World!\n");
    return 0;
}

然后,采用函數(shù)調(diào)用的形式來(lái)實(shí)現(xiàn):

void Invoke(char* s);

int main(int argc,char* argv[])
{
    Invoke("Hello World!\n");
    return 0;
}

void Invoke(char* s)
{
    printf(s);
}

用函數(shù)指針的方式來(lái)實(shí)現(xiàn):

void Invoke(char* s);

int main()
{
    void (*fp)(char* s);    //聲明一個(gè)函數(shù)指針(fp)        
    fp=Invoke;              //將Invoke函數(shù)的入口地址賦值給fp
    fp("Hello World!\n");   //函數(shù)指針fp實(shí)現(xiàn)函數(shù)調(diào)用
    return 0;
}

void Invoke(char* s)
{
    printf(s);
}

由上知道:函數(shù)指針函數(shù)的聲明之間唯一區(qū)別就是急黎,用指針名(fp)代替了函數(shù)名Invoke扎狱,這樣這聲明了一個(gè)函數(shù)指針侧到,然后進(jìn)行賦值fp=Invoke就可以進(jìn)行函數(shù)指針的調(diào)用了。聲明函數(shù)指針時(shí)淤击,只要函數(shù)返回值類(lèi)型匠抗、參數(shù)個(gè)數(shù)、參數(shù)類(lèi)型等保持一致污抬,就可以聲明一個(gè)函數(shù)指針了汞贸。注意,函數(shù)指針必須用括號(hào)括起來(lái) void (fp)(char* s)壕吹。

實(shí)際中,為了方便删铃,通常用宏定義的方式來(lái)聲明函數(shù)指針耳贬,實(shí)現(xiàn)程序如下:

typedef void (*FP)(char* s);
void Invoke(char* s);

int main(int argc,char* argv[])
{
    FP fp;      //通常是用宏FP來(lái)聲明一個(gè)函數(shù)指針fp
    fp=Invoke;
    fp("Hello World!\n");
    return 0;
}

void Invoke(char* s)
{
    printf(s);
}

函數(shù)指針數(shù)組
下面用程序?qū)瘮?shù)指針數(shù)組來(lái)個(gè)大致了解:

#include <iostream>
#include <string>
using namespace std;

typedef void (*FP)(char* s);
void f1(char* s){cout<<s;}
void f2(char* s){cout<<s;}
void f3(char* s){cout<<s;}

int main(int argc,char* argv[])
{
    void* a[]={f1,f2,f3};   //定義了指針數(shù)組,這里a是一個(gè)普通指針
    a[0]("Hello World!\n"); //編譯錯(cuò)誤猎唁,指針數(shù)組不能用下標(biāo)的方式來(lái)調(diào)用函數(shù)

    FP f[]={f1,f2,f3};      //定義一個(gè)函數(shù)指針的數(shù)組咒劲,這里的f是一個(gè)函數(shù)指針
    f[0]("Hello World!\n"); //正確,函數(shù)指針的數(shù)組進(jìn)行下標(biāo)操作可以進(jìn)行函數(shù)的間接調(diào)用
    
    return 0;
}

回調(diào)函數(shù)

(1)概念:回調(diào)函數(shù)诫隅,顧名思義腐魂,就是使用者自己定義一個(gè)函數(shù),使用者自己實(shí)現(xiàn)這個(gè)函數(shù)的程序內(nèi)容逐纬,然后把這個(gè)函數(shù)作為參數(shù)傳入別人(或系統(tǒng))的函數(shù)中蛔屹,由別人(或系統(tǒng))的函數(shù)在運(yùn)行時(shí)來(lái)調(diào)用的函數(shù)。函數(shù)是你實(shí)現(xiàn)的豁生,但由別人(或系統(tǒng))的函數(shù)在運(yùn)行時(shí)通過(guò)參數(shù)傳遞的方式調(diào)用兔毒,這就是所謂的回調(diào)函數(shù)。簡(jiǎn)單來(lái)說(shuō)甸箱,就是由別人的函數(shù)運(yùn)行期間來(lái)回調(diào)你實(shí)現(xiàn)的函數(shù)育叁。

(2)標(biāo)準(zhǔn)Hello World程序:

int main(int argc,char* argv[])
{
    printf("Hello World!\n");
    return 0;
}

將它修改成函數(shù)回調(diào)樣式:

//定義回調(diào)函數(shù)
void PrintfText() 
{
    printf("Hello World!\n");
}

//定義實(shí)現(xiàn)回調(diào)函數(shù)的"調(diào)用函數(shù)"
void CallPrintfText(void (*callfuct)())
{
    callfuct();
}

//在main函數(shù)中實(shí)現(xiàn)函數(shù)回調(diào)
int main(int argc,char* argv[])
{
    CallPrintfText(PrintfText);
    return 0;
}

修改成帶參的回調(diào)樣式:

//定義帶參回調(diào)函數(shù)
void PrintfText(char* s) 
{
    printf(s);
}

//定義實(shí)現(xiàn)帶參回調(diào)函數(shù)的"調(diào)用函數(shù)"
void CallPrintfText(void (*callfuct)(char*),char* s)
{
    callfuct(s);
}

//在main函數(shù)中實(shí)現(xiàn)帶參的函數(shù)回調(diào)
int main(int argc,char* argv[])
{
    CallPrintfText(PrintfText,"Hello World!\n");
    return 0;
}

至此,對(duì)回調(diào)函數(shù)應(yīng)該有了一個(gè)大致的了解芍殖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豪嗽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子豌骏,更是在濱河造成了極大的恐慌龟梦,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窃躲,死亡現(xiàn)場(chǎng)離奇詭異变秦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)框舔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén)蹦玫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)赎婚,“玉大人,你說(shuō)我怎么就攤上這事樱溉≌跏洌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵福贞,是天一觀(guān)的道長(zhǎng)撩嚼。 經(jīng)常有香客問(wèn)我,道長(zhǎng)挖帘,這世上最難降的妖魔是什么完丽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮拇舀,結(jié)果婚禮上逻族,老公的妹妹穿的比我還像新娘。我一直安慰自己骄崩,他們只是感情好聘鳞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著要拂,像睡著了一般免糕。 火紅的嫁衣襯著肌膚如雪噪生。 梳的紋絲不亂的頭發(fā)上单起,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天采记,我揣著相機(jī)與錄音,去河邊找鬼拉一。 笑死彻况,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舅踪。 我是一名探鬼主播纽甘,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼抽碌!你這毒婦竟也來(lái)了悍赢?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤货徙,失蹤者是張志新(化名)和其女友劉穎左权,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體痴颊,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赏迟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蠢棱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锌杀。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甩栈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出糕再,到底是詐尸還是另有隱情量没,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布突想,位于F島的核電站殴蹄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏猾担。R本人自食惡果不足惜袭灯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绑嘹。 院中可真熱鬧稽荧,春花似錦、人聲如沸圾叼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)夷蚊。三九已至,卻和暖如春髓介,著一層夾襖步出監(jiān)牢的瞬間惕鼓,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工唐础, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留箱歧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓一膨,卻偏偏與公主長(zhǎng)得像呀邢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子豹绪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 原文地址:C語(yǔ)言函數(shù)調(diào)用棧(一)C語(yǔ)言函數(shù)調(diào)用棧(二) 0 引言 程序的執(zhí)行過(guò)程可看作連續(xù)的函數(shù)調(diào)用价淌。當(dāng)一個(gè)函數(shù)執(zhí)...
    小豬啊嗚閱讀 4,591評(píng)論 1 19
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,090評(píng)論 1 32
  • 你總是可以?huà)佅挛胰プ瞿阕约合胱龅氖拢^(guò)後你告訴我瞒津,為什麼我不能理解你蝉衣。
    Insj閱讀 165評(píng)論 0 0
  • 美國(guó)作家、詩(shī)人馬婭·安杰盧(Maya Angelou)有句經(jīng)常被引用的話(huà):“人們會(huì)忘記你說(shuō)了什么巷蚪,也會(huì)忘記你做了什...
    我的秘密小窩閱讀 211評(píng)論 0 0
  • 2018強(qiáng)網(wǎng)杯已經(jīng)過(guò)去很久了剛好再整理一下通過(guò)這次比賽的一些個(gè)人收獲最后感慨病毡,自己實(shí)在太渣,要保持勤奮不斷前進(jìn) 0...
    云勺閱讀 613評(píng)論 1 1