0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言函數(shù)的回調函數(shù)

工程師 ? 來源:嵌入式客棧 ? 作者:嵌入式客棧 ? 2020-09-11 09:57 ? 次閱讀

來源:嵌入式客棧

1 什么是回調函數(shù)?首先什么是“回調”呢?

我的理解是:把一段可執(zhí)行的代碼像參數(shù)傳遞那樣傳給其他代碼,而這段代碼會在某個時刻被調用執(zhí)行,這就叫做回調。

如果代碼立即被執(zhí)行就稱為同步回調,如果過后再執(zhí)行,則稱之為異步回調。

回調函數(shù)就是一個通過函數(shù)指針調用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當這個指針被用來調用其所指向的函數(shù)時,我們就說這是回調函數(shù)。

回調函數(shù)不是由該函數(shù)的實現(xiàn)方直接調用,而是在特定的事件或條件發(fā)生時由另外的一方調用的,用于對該事件或條件進行響應。

2 為什么要用回調函數(shù)?因為可以把調用者與被調用者分開,所以調用者不關心誰是被調用者。它只需知道存在一個具有特定原型和限制條件的被調用函數(shù)。

簡而言之,回調函數(shù)就是允許用戶把需要調用的方法的指針作為參數(shù)傳遞給一個函數(shù),以便該函數(shù)在處理相似事件的時候可以靈活的使用不同的方法。

int Callback() ///《 回調函數(shù){ // TODO return 0;}int main() ///《 主函數(shù){ // TODO Library(Callback); ///《 庫函數(shù)通過函數(shù)指針進行回調 // TODO return 0;}

回調似乎只是函數(shù)間的調用,和普通函數(shù)調用沒啥區(qū)別。

但仔細看,可以發(fā)現(xiàn)兩者之間的一個關鍵的不同:在回調中,主程序把回調函數(shù)像參數(shù)一樣傳入庫函數(shù)。

這樣一來,只要我們改變傳進庫函數(shù)的參數(shù),就可以實現(xiàn)不同的功能,這樣有沒有覺得很靈活?并且當庫函數(shù)很復雜或者不可見的時候利用回調函數(shù)就顯得十分優(yōu)秀。

3 怎么使用回調函數(shù)?int Callback_1(int a) ///《 回調函數(shù)1{ printf(“Hello, this is Callback_1: a = %d ”, a); return 0;}int Callback_2(int b) ///《 回調函數(shù)2{ printf(“Hello, this is Callback_2: b = %d ”, b); return 0;}int Callback_3(int c) ///《 回調函數(shù)3{ printf(“Hello, this is Callback_3: c = %d ”, c); return 0;}int Handle(int x, int (*Callback)(int)) ///《 注意這里用到的函數(shù)指針定義{ Callback(x);}int main(){ Handle(4, Callback_1); Handle(5, Callback_2); Handle(6, Callback_3); return 0;}

如上述代碼:可以看到,Handle()函數(shù)里面的參數(shù)是一個指針,在main()函數(shù)里調用Handle()函數(shù)的時候,給它傳入了函數(shù)Callback_1()/Callback_2()/Callback_3()的函數(shù)名,這時候的函數(shù)名就是對應函數(shù)的指針,也就是說,回調函數(shù)其實就是函數(shù)指針的一種用法。

4 回調函數(shù)實例(很有用)一個GPRS模塊聯(lián)網(wǎng)的小項目,使用過的同學大概知道2G、4G、NB等模塊要想實現(xiàn)無線聯(lián)網(wǎng)功能都需要經(jīng)歷模塊上電初始化、注冊網(wǎng)絡、查詢網(wǎng)絡信息質量、連接服務器等步驟,這里的的例子就是,利用一個狀態(tài)機函數(shù)(根據(jù)不同狀態(tài)依次調用不同實現(xiàn)方法的函數(shù)),通過回調函數(shù)的方式依次調用不同的函數(shù),實現(xiàn)模塊聯(lián)網(wǎng)功能,如下:

/********* 工作狀態(tài)處理 *********/typedef struct{ uint8_t mStatus; uint8_t (* Funtion)(void); //函數(shù)指針的形式} M26_WorkStatus_TypeDef; //M26的工作狀態(tài)集合調用函數(shù)/************************************************ 》M26工作狀態(tài)集合函數(shù)***********************************************/M26_WorkStatus_TypeDef M26_WorkStatus_Tab[] ={ {GPRS_NETWORK_CLOSE, M26_PWRKEY_Off }, //模塊關機 {GPRS_NETWORK_OPEN, M26_PWRKEY_On }, //模塊開機 {GPRS_NETWORK_Start, M26_Work_Init }, //管腳初始化 {GPRS_NETWORK_CONF, M26_NET_Config }, /AT指令配置 {GPRS_NETWORK_LINK_CTC, M26_LINK_CTC }, //連接調度中心 {GPRS_NETWORK_WAIT_CTC, M26_WAIT_CTC }, //等待調度中心回復 {GPRS_NETWORK_LINK_FEM, M26_LINK_FEM }, //連接前置機 {GPRS_NETWORK_WAIT_FEM, M26_WAIT_FEM }, //等待前置機回復 {GPRS_NETWORK_COMM, M26_COMM }, //正常工作 {GPRS_NETWORK_WAIT_Sig, M26_WAIT_Sig }, //等待信號回復 {GPRS_NETWORK_GetSignal, M26_GetSignal }, //獲取信號值 {GPRS_NETWORK_RESTART, M26_RESET }, //模塊重啟}/************************************************ 》M26模塊工作狀態(tài)機,依次調用里面的12個函數(shù) ***********************************************/uint8_t M26_WorkStatus_Call(uint8_t Start){ uint8_t i = 0; for(i = 0; i 《 12; i++) { if(Start == M26_WorkStatus_Tab[i].mStatus) { return M26_WorkStatus_Tab[i].Funtion(); } } return 0;}

所以,如果有人想做個NB模塊聯(lián)網(wǎng)項目,可以copy上面的框架,只需要修改回調函數(shù)內部的具體實現(xiàn),或者增加、減少回調函數(shù),就可以很簡潔快速的實現(xiàn)模塊聯(lián)網(wǎng)。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7604

    瀏覽量

    136840
  • 函數(shù)
    +關注

    關注

    3

    文章

    4331

    瀏覽量

    62622
收藏 人收藏

    評論

    相關推薦

    同樣是函數(shù),在CC++中有什么區(qū)別

    同樣是函數(shù),在 CC++ 中有什么區(qū)別? 第一個返回值。 C語言函數(shù)可以不寫返回值類型,
    的頭像 發(fā)表于 11-29 10:25 ?308次閱讀

    使用C語言實現(xiàn)函數(shù)模板

      用C語言能不能實現(xiàn)一個通用的函數(shù),既能完成整數(shù)的相加,又能完成浮點數(shù)的相加?
    的頭像 發(fā)表于 11-09 11:38 ?390次閱讀

    定時器調函數(shù)能不能用ICACHE_FLASH_ATTR定義?

    非 OS SDK 在中斷處理函數(shù)中,請勿使用任何 ICACHE_FLASH_ATTR 定義的函數(shù)。 請問: 1、定時器和hw定時器的調函數(shù)
    發(fā)表于 07-22 06:33

    esp8266怎么找到調函數(shù)被調用的地方?

    esp8266里的程序怎么運行? 在user_init里注冊了espconn_regist_sentcb,espconn_regist_recvcb這幾個調函數(shù),怎么找到這幾個
    發(fā)表于 07-10 08:24

    在HTTP的demo里面,調函數(shù)不執(zhí)行的原因?

    在HTTP的demo里面,我用下面這個函數(shù)注冊了一個調函數(shù),但是發(fā)現(xiàn)有時候正常執(zhí)行有時候不執(zhí)行,只是偶爾不執(zhí)行,大部分時間是正常的。有沒有人能提供一下原因可能的方向,謝謝!! es
    發(fā)表于 07-10 08:23

    請問ESP32C3 I2S驅動支持調函數(shù)獲取數(shù)據(jù)嗎?

    目前I2S驅動只看到i2s_read接口獲取數(shù)據(jù),但這是polling方式的。是否有注冊調函數(shù),當數(shù)據(jù)到達是調用回頭函數(shù)通知上層app?
    發(fā)表于 06-28 06:11

    為什么無法停止使用cy_wcm_connect 的rtos定時器調函數(shù)

    。 由于 cy_wcm_connect() 函數(shù)的某些原因,計時器無法停止。 取而代之的是調用回調函數(shù),由于設備已連接到 Wifi,它將再次嘗試停止計時器。 我想知道如何以正確的方式停止計時器。 我測試了使用和不使用 cy_wc
    發(fā)表于 05-24 06:34

    stm32中斷調函數(shù)改變的變量在while中不變怎么解決?

    關于stm32 中斷調函數(shù)改變的變量在while中不變問題
    發(fā)表于 04-26 07:44

    stm32cubemx生成rtos后中斷處理后執(zhí)行的調函數(shù)是否也有優(yōu)先級?

    如題:調函數(shù)是否也有優(yōu)先級,我發(fā)現(xiàn)我的調函數(shù)不能按照預想的來運行.
    發(fā)表于 04-25 08:16

    請問ucos-III中斷保護放在中斷調函數(shù)還是中斷里面?

    請教下ucos-III 中斷保護放在中斷調函數(shù)還是中斷里面? 1. 中斷函數(shù) void DMA2_Stream6_IRQHandler(void) { OS_ERRerr
    發(fā)表于 04-23 07:44

    PHP用戶定義函數(shù)詳細講解

    描述 在所有編程和腳本語言中,函數(shù)是可以在程序中重復使用的語句塊。在 PHP 中,函數(shù)的概念與另一種語言(如“C”)中的概念相同。標準 PH
    的頭像 發(fā)表于 03-20 14:27 ?403次閱讀

    調函數(shù)(callback)是什么?調函數(shù)的實現(xiàn)方法

    調函數(shù)是一種特殊的函數(shù),它作為參數(shù)傳遞給另一個函數(shù),并在被調用函數(shù)執(zhí)行完畢后被調用。
    發(fā)表于 03-12 11:46 ?2944次閱讀

    淺談C語言中的函數(shù)定義

    如果函數(shù)要使用參數(shù),則必須聲明接受參數(shù)值的變量。這些變量稱為函數(shù)的形式參數(shù)。 形式參數(shù)就像函數(shù)內的其他局部變量,在進入函數(shù)時被創(chuàng)建,退出函數(shù)
    發(fā)表于 03-11 10:09 ?389次閱讀

    函數(shù)指針與調函數(shù)的應用實例

    通常我們說的指針變量是指向一個整型、字符型或數(shù)組等變量,而函數(shù)指針是指向函數(shù)。 函數(shù)指針可以像一般函數(shù)一樣,用于調用函數(shù)、傳遞參數(shù)。
    的頭像 發(fā)表于 03-07 11:13 ?401次閱讀
    <b class='flag-5'>函數(shù)</b>指針與<b class='flag-5'>回</b><b class='flag-5'>調</b><b class='flag-5'>函數(shù)</b>的應用實例

    ??嵌入式中調函數(shù)的實現(xiàn)方法

    調函數(shù)的命名規(guī)范沒有固定的標準,但是根據(jù)通用慣例和編碼規(guī)范,調函數(shù)的命名應該能夠反映
    發(fā)表于 03-04 14:49 ?723次閱讀