亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

c語言中回調函數的使用以及實際作用詳析

 更新時間:2021年07月18日 08:46:40   作者:無際單片機編程  
回調函數就是一個通過函數指針調用的函數,如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數,這篇文章主要給大家介紹了關于c語言中回調函數的使用以及實際作用的相關資料,需要的朋友可以參考下

前言

今天給大家講一下芯片/模塊廠家寫SDK必須會使用的一種技術:回調函數。

回調函數這個知識點其實并不是很難,難是難在網上很多講解回調函數的都說的太學術化了化了,一點也不親民。

很多人即使知道怎么寫回調函數也根本就搞不懂它們在實際產品中也有什么用,什么時候用。

所以這節(jié)課呢我們會以程序架構的需求為出發(fā)點,講解回調函數是怎么滿足它這個需求的。

為了方便大家理解,這篇內容也對應有一篇文章,大家可以找無際單片機編程獲取。

一、通過這節(jié)課程你能掌握以下知識:

掌握程序架構的核心理念或需求。掌握回調函數的作用掌握回調函數的程序編寫掌握回調函數在產品中的應用

二、程序架構的核心理念和需求

很多人可能會說一個好的程序架構啊,就是代碼很緊湊、執(zhí)行效率也很高。

其實這個說的很片面,不完全對,這只能說明你程序算法寫的好,但架構不一定做的好。

即然是架構,那自然是以從”大局”為重,思維不能局限于當下的產品功能,還要考慮到以后功能的增加和裁剪,那么對于單片機開發(fā)來說,我認為一個好的程序架構至少要達到以下要求:

硬件層和應用層的程序代碼分開,相互之間的控制和通訊使用接口,而且不會共享的全局變量或數組。

這里呢,我就這個要求,別小看這一個要求,因為這個要求里面蘊藏著很多學問的,比如用專業(yè)稱為可移植性、可擴展性。

那么我們來想象一下我們通常寫單片機代碼的方式啊,在51的時候基本一個.c文件解決,包括寄存器配置啊,產品功能啊。

這種就是沒有架構的程序,然后我們進化到STM32這個單片機以后,程序大了,慢慢也會在工程文件里加幾個文件夾目錄把硬件層和應用層代碼分開了。

于是我們會把一些不同的外設功能,比如Led、按鍵、串口等外設功能代碼分別寫在不同的.c文件里,然后統(tǒng)一用函數接口去調用它。

比方說控制一個LED燈亮,直接在led.c文件里寫一個驅動led燈狀態(tài)的函數然后給外部調用就好了。

那我們我們看這種Led的控制函數確實也是滿足程序架構的需求的,硬件層和應用層代碼分開,應用層用硬件層提供的接口來控制,而且又不會有硬件層和應用層共享的全部變量或數組。像這種是不是很簡單?

那么不知道你們有沒有碰到另外一種情況,就是應用程序需要采集硬件層的數據,比如串口接收數據,按鍵采集、ADC值采集。

這種硬件層的數據怎么通知應用層來拿,或者怎么主動給它?

我們以往最簡單粗暴的方式是不是就是用一個全局變量,比方說硬件層串口接收到數據來了,那么我們把數據丟到數組里,然后把接收完成全局變量標志位置1。

比方說全局變量名為RcvFlag,然后應用層程序會輪詢判斷RcvFlag==1?是的話就開始把數組里的數據取出來解析。

很多人就會說了,你看我用這種方法照樣能實現功能啊,為什么還要學習別的架構。

這樣做當然可以實現功能,但是會存在移植性很差的問題。

比如說你們老板讓你把這個串口的硬件層封裝起來給客戶用,但不能讓客戶看到你實現的源代碼,只提供接口(函數名)給對方用。

那么這時候難道你要告訴客戶先判斷哪個變量為1,然后再取哪個數組的數據這么LOW的做法嗎?

那么如果是懂行的客戶一定會懷疑你們公司的技術實力是不是小學生水平。

那怎樣做才會既方便又專業(yè)呢? 這里我們就需要用到回調函數啦。

三、回調函數的作用

那么在講回調函數之前呢,對于函數調用呢我一般分為2種類型:

1.輸出型

不知道大家有沒有用過C語言自帶的一些庫函數,比如說sizeof()獲取數據長度的函數,memcpy()是內存拷貝函數,我們調用這個函數之后呢就能完成相應的功能。

還有我們基于單片機的一些程序函數,比方說控制LED點亮熄滅、繼電器吸合斷開、LCD驅動等等。

那么這些呢,我一般稱為輸出型的函數。

輸出型函數我們是主導的角色,我們知道什么時候該調用它。

2.輸入型

輸入型呢,也稱為的是響應式的函數。

什么叫響應式的函數呢?

比方說接收串口的數據,我們不知道什么數據什么時候來。

再比方說,我們按鍵檢測的函數,我們不知道什么時候會按下按鍵,那么這些就要定義成響應式函數來實現,而響應式函數就可以用回調函數來實現。

所以通過這兩個種類型的分析啊,我們就可以知道,回調函數基本是用在輸入型的處理中。

比方說串口數據接收,那么數據是輸入到單片機里面的,單片機是處于從機角色。

按鍵檢測,按鍵狀態(tài)是輸入到單片機里的。

再比方說ADC值采集,ADC值也是輸入到單片機里的。

那么它們輸入的時間節(jié)點都是未知的,這些就能夠用回調函數來處理。

具體怎么處理后面我們會用代碼來給大家舉例。

回調函數還有一個作用就是為了封裝代碼

比如說做芯片或者模組的廠家,我們拿典型的STM32來舉例,像外部中斷、定時器、串口等中斷函數都是屬于回調函數,這種函數的目的是把采集到的數據傳遞給用戶,或者說應用層。

所以回調函數的核心作用是:

1.把數據從一個.c文件傳遞到另一個.c文件,而不用全局變量共享數據這么LOW的方法。

2.對于這種數據傳遞方式,回調函數更利于代碼的封裝。

四、掌握回調函數的程序編寫

前面說了很多概念性的東西,可能大家也比較難理解,回調函數最終呢是靠函數指針來實現的。

那么我這里通過一些模擬按鍵的例子來演示下怎么回通過調函數來處理它們。

下面是我們的c-free工程,用這個來模擬方便點:

從模塊化編程的思想來看,整個工程分為2個部分,應用層main.c文件,硬件層key.c和key.h文件。

不管再怎么復雜的程序,我們都要先從main函數一步步往下挖,main函數代碼如下。

int main(int argc, char *argv[])
{
KeyInit();
KeyScanCBSRegister(KeyScanHandle);
KeyPoll();
 
return 0;
}

KeyInit();是key.c文件的按鍵初始化函數

KeyScanCBSRegister(KeyScanHandle);是key.c的函數指針注冊函數。

這個函數可能大家會有點蒙,請跟進我們的節(jié)奏,下面開始燒腦環(huán)節(jié),也是寫回調函數的必須步驟,

想理解這個回調函數注冊函數,我們要先從硬件層(key.h)頭文件的函數指針定義說起,具體看下圖。

這里自定義了一個函數指針類型,帶兩個形參。

然后,我們在key.c這個文件里定義了一個函數指針變量。

重點來了,我們就是通過這個函數指針,指向應用層的函數地址(函數名)

具體怎么實現指向呢?就是通過函數指針注冊函數。

這個函數是在main函數里調用,使用這種注冊函數的方式注冊靈活性也很高,你想要在哪個.c文件使用按鍵功能就在哪里調用。

這里要注意,main.c這個文件要定義一個函數來接收硬件層(key.c)過來的數據。

這里定義也不是亂定義的,一定要和那個自定義函數指針類型返回值、形參一致。

然后把這個函數名字直接復制給KeyScanCBSRegister函數的形參就可以了。

這樣調用后,我們key.c文件的pKeyScanCBS這個指針其實就是指向的KeyScanHandle函數。

也就是說執(zhí)行pKeyScanCBS的時候,就是執(zhí)行KeyScanHandle函數。

那具體檢測按鍵的功能就是KeyPoll函數,這個在main函數里調用。

當檢測到鍵盤有輸入以后,最終會調用pKeyScanCBS。

最終執(zhí)行的是main.c文件的KeyScanHandle函數。

所以,我們來看下輸出結果。

如果還是有點模糊,下面我再給大家捋一捋編寫和使用回調函數的流程:

  1. 自定義函數指針,形參作為硬件層要傳到應用層的數據。
  2. 硬件層定義一個函數指針和函數指針注冊函數。
  3. 應用層定義一個函數,返回值和形參都要和函數指針一致。
  4. 應用層調用函數指針注冊函數,把定義好的函數名稱作為形參傳入。

Ok,這就是回調函數的使用。

如果還看不懂建議多看兩遍。

下面請大家思考一下,這個程序雖然簡單,但是不是架構還不錯?應用層和硬件層完全獨立?

總結

到此這篇關于c語言中回調函數的使用以及實際作用的文章就介紹到這了,更多相關c語言回調函數使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++計算每個字符出現的次數

    C++計算每個字符出現的次數

    這篇文章主要介紹了C++計算每個字符出現的次數的相關資料,需要的朋友可以參考下
    2016-05-05
  • getdate()函數的用法實例

    getdate()函數的用法實例

    getdate()函數的用法實例,需要的朋友可以參考一下
    2013-03-03
  • C++學校運動會管理系統(tǒng)的實現

    C++學校運動會管理系統(tǒng)的實現

    這篇文章主要為大家詳細介紹了C++如何實現學校運動會管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • 深入理解大數與高精度數的處理問題

    深入理解大數與高精度數的處理問題

    本篇文章是對大數與高精度數的處理進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Qt Design Studio創(chuàng)建工程的實現方法

    Qt Design Studio創(chuàng)建工程的實現方法

    Qt Design Studio它允許設計人員和開發(fā)人員使用通用的設計、開發(fā)、分析和調試工具在不同的開發(fā)平臺上共享一個項目,本文主要介紹了Qt Design Studio創(chuàng)建工程的實現方法,具有一定的參考價值,感興趣的可以了解一下
    2022-05-05
  • 詳解C++模板編程中typename用法

    詳解C++模板編程中typename用法

    typename在C++類模板或者函數模板中經常使用的關鍵字,此時作用和class相同,只是定義模板參數,下面通過例子給大家介紹c++模板typename的具體用法,一起看看吧
    2021-07-07
  • 200行C語言代碼實現簡易三子棋游戲

    200行C語言代碼實現簡易三子棋游戲

    三子棋(井字棋)我們的童年或多或少都體驗過這個游戲的樂趣,本子隨手一畫就是一局游戲的開始,下面這篇文章主要給大家介紹了關于200行C語言代碼實現簡易三子棋游戲的相關資料,需要的朋友可以參考下
    2023-05-05
  • C++中類的三種訪問權限解析:private、public與protect

    C++中類的三種訪問權限解析:private、public與protect

    這篇文章主要介紹了C++中類的三種訪問權限解析:private、public與protect,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 基于VC編寫COM連接點事件的分析介紹

    基于VC編寫COM連接點事件的分析介紹

    本篇文章是對VC編寫COM連接點事件進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • c++中的指針最全總結

    c++中的指針最全總結

    指針是整個C++的精髓所在,只有精通了指針才可以說是掌握了C++,可以說學習C++的過程是個熟練掌握和使用指針的過程,下面這篇文章主要給大家介紹了關于c++中指針的相關資料,需要的朋友可以參考下
    2024-04-04

最新評論