在網上看了許多關於回調函數的解釋,感受沒能get到主要的一個點,就本身寫一下對回調函數的理解及回調函數的應用場景和做用吧函數
一、官方定義spa
回調函數就是一個經過函數指針調用的函數。若是你把函數的指針(地址)做爲參數傳遞給另外一個函數,當這個指針被用來調用其所指向的函數時,咱們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。設計
二、函數指針指針
理解回調函數前必須知道什麼是函數指針code
函數指針也是一種指針,只是它指向的不是整型,字符型而是函數。在C中,每一個函數在編譯後都是存儲在內存中,而且每一個函數都有一個入口地址,根據這個地址,咱們即可以訪問並使用這個函數。函數指針就是經過指向這個函數的入口,從而調用這個函數。blog
int fun();
int (*p)();
fun是一個返回值爲整型的函數
p是一個指針,指針指向一個函數,函數的返回值是整型
p = fun; 函數fun把地址賦給函數指針p
下次調用fun()能夠直接用 (*p)( ) 或者 p( ) 事件
爲何能夠直接用p(),由於函數名本質也是一個地址,函數指針本質也是一個地址,把地址fun賦給地址p ,p不就等於fun了嗎,(*p)和p至關於間接訪問和直接訪問的關係,不用糾結過多內存
三、回調函數get
回調函數就是你寫一個函數,把函數地址賦值一個函數指針,而後把這個函數指針看成參數賦給另外一個函數,另外一個函數經過函數指針的地址調用這個函數,就是回調函數,他有什麼做用呢,舉個例子
好比,咱們寫A B C D 四個函數,封裝成一個庫文件,而後咱們的主函數裏面要寫一個功能函數,這個功能要用到函數A,假如不用函數指針,這個功能函數就要調用函數A,下次若是用到函數B,那麼咱們得刪掉A,調用函數B,每次都要修改這個函數很麻煩,但若是使用回調函數就不同了,咱們能夠定義4個函數指針,把4個函數的地址分別賦給4個函數指針,而後將函數指針看成參數傳遞給功能函數,功能函數就能夠經過修改參數來調用對應的函數,而它自己不用作任何的修改。這樣的話,功能函數就能夠根據不一樣的狀況,經過函數指針去調用不一樣的函數,代碼以下回調函數
#include <stdio.h> #include <stdlib.h> float ADD(float a, float b) { return a + b; } float SUB(float a, float b) { return a - b; } float MUL(float a, float b) { return a * b; } float DIV(float a, float b) { return a / b; } float (*A)(float x, float y) = ADD; float (*B)(float x, float y) = SUB; float (*C)(float x, float y) = MUL; float (*D)(float x, float y) = DIV; float fun(float x, float y, float(*p)(float x, float y)) { return p(x, y); } int main() { printf("%f", fun(2, 3, A)); }
再舉一個例子,咱們要實現一個函數,函數的功能是查找鏈表裏面的某一個值,那麼函數設計兩個參數,一個是鏈表第一個結點的指針,還有一個要查找的數,這時候問題就來了,鏈表的值多是整型,也多是字符,不一樣的類型對應的參數類型也不一樣,比較的方式也不一樣,這時候就須要用到回調函數,能夠寫一個比較兩個值的函數,而後把函數地址賦值給一個函數指針,函數指針看成參數放到功能函數裏做爲第三個參數,功能函數就能夠經過函數指針調用比較函數,並把兩個值傳給回調函數,比較函數獲取到兩個值後,經過強制類型轉換比較兩個值,返回結果。代碼如圖
但願能夠經過這兩個例子幫助你們理解回調函數的使用,回調函數本質上就是函數指針的原理
轉載請註明出處、做者,謝謝