回撥函式的作用

陳佳樂發表於2019-07-31

在網上看了許多關於回撥函式的解釋,感覺沒能get到主要的一個點,就自己寫一下對回撥函式的理解及回撥函式的應用場景和作用吧

1、官方定義

回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是回撥函式。回撥函式不是由該函式的實現方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用於對該事件或條件進行響應。

2、函式指標

理解回撥函式前必須知道什麼是函式指標

函式指標也是一種指標,只是它指向的不是整型,字元型而是函式。在C中,每個函式在編譯後都是儲存在記憶體中,並且每個函式都有一個入口地址,根據這個地址,我們便可以訪問並使用這個函式。函式指標就是通過指向這個函式的入口,從而呼叫這個函式。

int fun();
int (*p)();
fun是一個返回值為整型的函式
p是一個指標,指標指向一個函式,函式的返回值是整型
p = fun; 函式fun把地址賦給函式指標p
下次呼叫fun()可以直接用   (*p)( ) 或者  p( )

為什麼可以直接用p(),因為函式名本質也是一個地址,函式指標本質也是一個地址,把地址fun賦給地址p ,p不就等於fun了嗎,(*p)和p相當於間接訪問和直接訪問的關係,不用糾結過多

3、回撥函式

回撥函式就是你寫一個函式,把函式地址賦值一個函式指標,然後把這個函式指標當作引數賦給另一個函式,另一個函式通過函式指標的地址呼叫這個函式,就是回撥函式,他有什麼作用呢,舉個例子
比如,我們寫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));

}


再舉一個例子,我們要實現一個函式,函式的功能是查詢連結串列裡面的某一個值,那麼函式設計兩個引數,一個是連結串列第一個結點的指標,還有一個要查詢的數,這時候問題就來了,連結串列的值可能是整型,也可能是字元,不同的型別對應的引數型別也不同,比較的方式也不同,這時候就需要用到回撥函式,可以寫一個比較兩個值的函式,然後把函式地址賦值給一個函式指標,函式指標當作引數放到功能函式裡作為第三個引數,功能函式就可以通過函式指標呼叫比較函式,並把兩個值傳給回撥函式,比較函式獲取到兩個值後,通過強制型別轉換比較兩個值,返回結果。程式碼如圖

 

希望可以通過這兩個例子幫助大家理解回撥函式的使用,回撥函式本質上就是函式指標的原理

轉載請註明出處、作者,謝謝

相關文章