2020-08-12

2020-08-12 23:39:42

函數也可以作爲函數的參數來傳遞。
在庫函數呼叫,尤其是嵌入式開發中經常能用到回撥函數。
那什麼是回撥函數?
其實很簡單,舉個網上看到的一個通俗的列子:
約會結束後你送你女朋友回家,離別時,你肯定會說:「到家了給我發條資訊,我很擔心你」 ,然後你女朋友回家以後還真給你發了條資訊:「小夥子,你有戲了」。其實這就是一個回撥的過程。你留了個參數函數(要求女朋友給你發條資訊)給你女朋友,然後你女朋友回家,回家的動作是主函數。她必須先回到家以後,主函數執行完了,再執行傳進去的函數,然後你就收到一條資訊了。

下面 下麪寫一個程式:
比如某庫函數功能有一個功能:當x任務發生時,列印「Hallo,word!」(當然具體可能是一個很複雜的功能),爲了能滿足各種要求,這個x任務可以由使用者自己來定義,這個由使用者自己來定義的函數就稱爲回撥函數。

#include<stdio.h>

int Callback_1(void)
{
    printf("Hello\n");
    return 0;
}

int Callback_2(void)
{   
    printf("world\n");
    return 0;
}

int Handle(int (*Callback)(void))
{
    Callback();
    printf("Hello,world!\n");
}
int main()
{
    Handle(Callback_1);
    Handle(Callback_2);
    return 0;
}

在这里插入图片描述
其實回撥函數就是把函數當作參數,Handle呼叫Callback_1實現了先執行列印"Hello",再執行列印"Hello,world!";呼叫Callback_1實現了先執行列印"world",再執行列印"Hello,world!",當然具體應用中回撥函數的功能不可能這樣簡單。
下面 下麪是帶參數的:

#include<stdio.h>

int Callback_1(int *x)
{
    printf("Hello,a=%d\n",*x);
    return 0;
}

int Callback_2(char *p)
{   
    printf("%s",p);
    printf("world\n");
    return 0;
}

int Handle(void*k,int (*Callback)(void*))
{
    Callback(k);
    printf("Hello,world!\n");
}
int main()
{
    int a = 10;
    char* p = "hi";
    Handle(&a,Callback_1);
    Handle(p,Callback_2);
    return 0;
}

執行結果:
在这里插入图片描述
可能在我們自己寫程式中用處不大,一但當專案很大的時候,就會非常方便了,比如stm32的庫函數中,FreeRTOS中呼叫api函數等。