激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C/C++ - c語言中回調(diào)函數(shù)的使用以及實際作用詳析

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

2021-11-30 13:35無際單片機編程 C/C++

回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù),如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當(dāng)這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù),這篇文章主要給大家介紹了關(guān)于c語言中回調(diào)函數(shù)的使用以及實際

前言

今天給大家講一下芯片/模塊廠家寫sdk必須會使用的一種技術(shù):回調(diào)函數(shù)。

回調(diào)函數(shù)這個知識點其實并不是很難,難是難在網(wǎng)上很多講解回調(diào)函數(shù)的都說的太學(xué)術(shù)化了化了,一點也不親民。

很多人即使知道怎么寫回調(diào)函數(shù)也根本就搞不懂它們在實際產(chǎn)品中也有什么用,什么時候用。

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

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

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

掌握程序架構(gòu)的核心理念或需求。掌握回調(diào)函數(shù)的作用掌握回調(diào)函數(shù)的程序編寫掌握回調(diào)函數(shù)在產(chǎn)品中的應(yīng)用

二、程序架構(gòu)的核心理念和需求

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

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

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

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

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

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

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

這種硬件層的數(shù)據(jù)怎么通知應(yīng)用層來拿,或者怎么主動給它?

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

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

很多人就會說了,你看我用這種方法照樣能實現(xiàn)功能啊,為什么還要學(xué)習(xí)別的架構(gòu)。

這樣做當(dāng)然可以實現(xiàn)功能,但是會存在移植性很差的問題。

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

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

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

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

三、回調(diào)函數(shù)的作用

那么在講回調(diào)函數(shù)之前呢,對于函數(shù)調(diào)用呢我一般分為2種類型:

1.輸出型

不知道大家有沒有用過c語言自帶的一些庫函數(shù),比如說sizeof()獲取數(shù)據(jù)長度的函數(shù),memcpy()是內(nèi)存拷貝函數(shù),我們調(diào)用這個函數(shù)之后呢就能完成相應(yīng)的功能。

還有我們基于單片機的一些程序函數(shù),比方說控制led點亮熄滅、繼電器吸合斷開、lcd驅(qū)動等等。

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

輸出型函數(shù)我們是主導(dǎo)的角色,我們知道什么時候該調(diào)用它。

2.輸入型

輸入型呢,也稱為的是響應(yīng)式的函數(shù)

什么叫響應(yīng)式的函數(shù)呢?

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

再比方說,我們按鍵檢測的函數(shù),我們不知道什么時候會按下按鍵,那么這些就要定義成響應(yīng)式函數(shù)來實現(xiàn),而響應(yīng)式函數(shù)就可以用回調(diào)函數(shù)來實現(xiàn)

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

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

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

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

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

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

回調(diào)函數(shù)還有一個作用就是為了封裝代碼

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

所以回調(diào)函數(shù)的核心作用是:

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

2.對于這種數(shù)據(jù)傳遞方式,回調(diào)函數(shù)更利于代碼的封裝。

四、掌握回調(diào)函數(shù)的程序編寫

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

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

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

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

?
1
2
3
4
5
6
7
8
int main(int argc, char *argv[])
{
keyinit();
keyscancbsregister(keyscanhandle);
keypoll();
 
return 0;
}

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

keyscancbsregister(keyscanhandle);是key.c的函數(shù)指針注冊函數(shù)。

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

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

具體怎么實現(xiàn)指向呢?就是通過函數(shù)指針注冊函數(shù)。

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

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

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

然后把這個函數(shù)名字直接復(fù)制給keyscancbsregister函數(shù)的形參就可以了。

這樣調(diào)用后,我們key.c文件的pkeyscancbs這個指針其實就是指向的keyscanhandle函數(shù)。

也就是說執(zhí)行pkeyscancbs的時候,就是執(zhí)行keyscanhandle函數(shù)。

那具體檢測按鍵的功能就是keypoll函數(shù),這個在main函數(shù)里調(diào)用。

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

當(dāng)檢測到鍵盤有輸入以后,最終會調(diào)用pkeyscancbs。

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

所以,我們來看下輸出結(jié)果。

c語言中回調(diào)函數(shù)的使用以及實際作用詳析

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

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

ok,這就是回調(diào)函數(shù)的使用。

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

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

總結(jié)

到此這篇關(guān)于c語言中回調(diào)函數(shù)的使用以及實際作用的文章就介紹到這了,更多相關(guān)c語言回調(diào)函數(shù)使用內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://blog.csdn.net/weixin_43982452/article/details/118832603

延伸 · 閱讀

精彩推薦
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言實現(xiàn)電腦關(guān)機程序

    C語言實現(xiàn)電腦關(guān)機程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)電腦關(guān)機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典實例之模擬計算器的相關(guān)資料,文中通過示...

    jia150610152021-06-07
  • C/C++學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復(fù)制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當(dāng)程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關(guān)于C語言中文件...

    針眼_6702022-01-24
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
主站蜘蛛池模板: 欧美一区二区黄 | 国产精品久久久网站 | 国产精品亚洲综合一区二区三区 | 视屏一区 | 日韩黄色免费电影 | 欧美1—12sexvideos | 国产精品久久久久久久久久久久久久久 | 国产91在线高潮白浆在线观看 | 亚洲成人精品区 | 久久99久久99免费视频 | 欧美一级性 | 人成免费a级毛片 | 久久久噜噜噜久久熟有声小说 | 亚洲成人涩涩 | 狠狠干五月 | 在线观看国产网站 | 羞羞电影网 | 成年人黄色免费网站 | 99欧美精品 | 日韩精品一区二 | 亚洲日韩中文字幕一区 | 精品中文字幕视频 | 国产精品久久久久久久久久 | 一级空姐毛片 | 久久99精品久久 | 久久免费视频一区二区三区 | av在线免费看网站 | 一级毛片在线看 | 三级国产三级在线 | 人成久久 | 91精品国产91久久久久久 | 欧美日韩高清一区 | 亚洲国产视频在线 | 99日韩精品视频 | 欧美成人免费看 | 一级尻逼视频 | 免费激情视频网站 | 国产精品毛片无码 | 午夜在线小视频 | 精品亚洲在线 | 久久久久久久久91 |