標題: 關于C語言回調函數的理解 [打印本頁]
作者: IdeaMing 時間: 2019-1-3 14:03
標題: 關于C語言回調函數的理解
回調函數的理解
前言: 剛開始用C語言聽說過回調函數,但沒有仔細去理解,隨著工作的慢慢積累,逐步的用到了回調函數,本人認為,“回調函數”的理解對于很多人是一個檻,要想跨過,就得理解清楚,還得會用。這里就用本人的方式講解一下回調函數如何理解。如有問題,歡迎指正mr.li.ming@qq.com。
第一步:通俗的解釋“回調函數”一、回調就是一種利用函數指針進行函數調用的過程。
二、你到一個商店買東西,剛好你要的東西沒有貨,于是你在店員那里留下了你的電話,過了幾天店里有貨了,店員就打了你的電話,然后你接到電話后就到店里去取了貨。
三、回調函數是指 使用者自己定義一個函數,實現這個函數的程序內容,然后把這個函數(入口地址)作為參數傳入別人(或系統)的函數中,由別人(或系統)的函數在運行時來調用的函數。函數是你實現的,但由別人(或系統)的函數在運行時通過參數傳遞的方式調用,這就是所謂的回調函數。簡單來說,就是由別人的函數運行期間來回調你實現的函數。
注:以上解釋均摘自網絡,感謝這些大佬的解釋。
或許到這里你已經明白了那么個意思,但是問題來了:
1. 怎么看出來就是一個回調函數呢?
2. 怎么定義一個回調函數呢?
3. 怎么使用回調函數呢?
帶著問題我們看實例,然后再解釋。
第二步:實例解釋
- #include "stdio.h"
- int sub(int a, int b)//求和函數
- {
- return a+b;
- }
- int mul(int a, int b)//求積函數
- {
- return a*b;
- }
- int test(int(*p)(int,int), int a, int b)//測試函數
- {
- return (*p)(a, b);
- }
- void main(void)
- {
- int a = 8;
- int b = 2;
- int temp;
- temp = test(sub, a, b);
- printf("%d\n",temp);
- temp = test(sub, a, b);
- printf("%d\n",temp);
- }
- 執行結果就是
- 10 //8+2
- 16 //8*2
復制代碼主要分析這個test函數,它的三個輸入參數分別是
int(*p)(int, int) int a int b
后面兩個好理解,就是跟常見的一樣,是一個函數的兩個輸入參數。
第一個要怎么理解呢?
首先看到有*p,這是一個指針了,類比到int *a這種定義方式來理解。
Int temp; //定義一個int型的變量,名稱是temp
Int *a;//定義一個 名稱為a的指針這個指針限定的范圍是“int型變量”
那么int(*p)(int, int)它的意思是:定義一個名稱為p的函數指針, p指向的函數要求有兩個int輸入參數,而且要求這個函數返回值是int型。
那么趁熱打鐵void(*p)(int, int)的意思就是:定義一個名稱為p的函數指針, p指向的函數要求有兩個int輸入參數,而且要求這個函數返回值是void型(即沒有)。
void(*p)(int)的意思就是:定義一個名稱為p的函數指針, p指向的函數要求有一個int輸入參數,而且要求這個函數返回值是void型(即沒有)。
char(*p)(int)的意思就是:定義一個名稱為p的函數指針, p指向的函數要求有一個int輸入參數,而且要求這個函數返回值是char型。
那么現在有沒有明白這個參數的定義呢?
有篇資料中有這么一段
『函數指針的定義比較怪,為什么不是 void ()(int, int, float) *p_func
而是 void(*p_func)(int, int, float) 這種形式?』
這個問題我也不知道,也沒必要糾結,花點時間理解下它與普通指針的區別,記住這就是它的定義形式。
到這里:總結一下,上面的這么多都是在解釋一個“函數指針”。理解了函數指針,我們再看一下
int test(int(*p)(int,int), int a, int b)//測試函數
{
return (*p)(a, b);
}
這個test函數是把 p 這個函數指針作為一個輸入參數。
temp = test(sub, a, b);
這一句呢,就是把p指向sub這個函數, Sub要求有兩個int輸入參數。
Return (*p)(a,b);就是
Return sub(a,b);這里 *p這個參數起作用了,這個參數就是sub函數,就是一個算法。
第三步:疑問解惑現在來回答第一步的三個問題了:
1、 怎么看出來就是一個回調函數呢?
像test函數那樣,用了函數指針作為輸入參數的函數就是回調函數,這種函數會調用另外一個函數作為輸入參數。
2、 怎么定義一個回調函數呢?
回調函數定義跟上面的識別是反過來的,定義一個函數,它的輸入參數中有函數指針,那么你就定義了一個回調函數。
3、 怎么使用回調函數呢?
使用回調函數的地方有很多,一般用于封裝的程序給開發人員留出后期開發接口。
- int test(int(*p)(int,int), inta, int b)
- {
- Int temp;
- temp = (*p)(a, b);
- if(temp != 0)
- return OK;
- else
- return FAIL;
- }
復制代碼這樣修改test函數,然后封裝起來,test函數只做結果是否不為0的判斷,后期開發人員可以把計算函數指針,和參與計算的兩個參數輸入給test,test就能返回OK或者FAIL。雖然這個test函數已經固定了,但后期開發人員依然可以隨便更改計算函數。
下面是本文的pdf文檔
回調函數的理解.pdf
(445.58 KB, 下載次數: 64)
2019-1-3 14:09 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者: cyhauxiang 時間: 2019-6-21 01:30
講的很好,謝謝!
作者: chenyh85 時間: 2019-11-23 16:20
很好,聽懂了~~~
作者: williamfang 時間: 2019-12-18 16:12
很好,清晰易懂,謝謝!上面第二步:實例解釋,代碼中第21行temp = test(sub, a, b);應該是筆誤,應該是temp = test(mul, a, b);
作者: IdeaMing 時間: 2020-4-16 09:27
確實是寫錯了,謝謝提醒,已經無法修改了,希望后面讀者注意一下。
作者: 淡定120 時間: 2020-8-20 14:26
很好,清晰易懂!
作者: ozp2003 時間: 2020-11-17 15:05
這幾天剛接觸STM32的HAL庫,剛知道回調函數,我的理解就是中斷或者別的執行的時候,通過函數指針調用回調函數,然后返回,查網上的理解是方便后期開發人員在調用的回調函數中開發!但是又冒出新疑問,網上解釋說回調函數是并行的,其實回調函數與并行與否無關系,僅僅是用了函數指針,樓主的例子也可以說明,不存在是否并行!那么HAL庫的說法是并行的,那么問題來了,進入中斷后清了中斷標志,假設執行回調函數的時候,外部又觸發了中斷咋辦?外面排隊還是又觸發中斷,理論上說,清了標志位,那就可以再次中斷了~~
作者: sj904 時間: 2020-11-18 11:39
剛學了復雜聲明就看到樓主的貼子,很是受益,書上是這么說的,因為函數不能直接做形參,所以要在形參里調用函數時,要用指針的方式。
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
久久性色|
欧美一区成人
|
一区二区三区四区在线视频
|
一级特黄a大片
|
欧美一二区
|
日韩三级一区
|
午夜三级在线观看
|
午夜伦理影院
|
中国一级大黄大片
|
亚洲成人av
|
www.色午夜.com
|
国产精品明星裸体写真集
|
日韩成人av在线
|
99爱在线|
亚洲在线免费观看
|
男女羞羞视频在线
|
亚洲一区二区三区在线播放
|
亚洲一区二区三区四区五区午夜
|
a爱视频
|
日韩精品成人
|
91久久精品一区二区二区
|
狠狠干天天干
|
国产高清视频在线观看
|
欧美在线视频网站
|
一区二区免费
|
久久亚洲国产精品日日av夜夜
|
一区二区三区四区在线视频
|
日韩欧美精品在线
|
久久午夜视频
|
色视频网站在线观看
|
亚洲精品9999
|
日一区二区|
一区二区亚洲
|
在线欧美亚洲
|
美美女高清毛片视频免费观看
|
涩涩视频在线观看免费
|
一区二区三区免费观看
|
一区二区高清在线观看
|
在线观看亚洲精品
|
亚洲一区二区三区在线播放
|
国产黄色网
|