欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言中回調(diào)函數(shù)的含義與使用場景詳解

 更新時(shí)間:2022年03月28日 09:13:19   作者:物聯(lián)網(wǎng)老王  
這篇文章主要為大家詳細(xì)介紹了C語言中回調(diào)函數(shù)的含義與使用場景,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

舉例

在下述程序中函數(shù) test2_cal() 中調(diào)用 函數(shù)指針 s_cal 指定的函數(shù)執(zhí)行數(shù)值的計(jì)算。則 s_cal 指定的那些函數(shù)就可以看作一個(gè)回調(diào)函數(shù)。

typedef int (*my_calculate_t)(int a, int b);
static int cal_sum(int a, int b)
{
    printf("now is sum\r\n");
    return a + b;
}
static int cal_sub(int a, int b)
{
    printf("now is sub\r\n");
    return a - b;
}
static int cal_mul(int a, int b)
{
    printf("now is mul\r\n");
    return a * b;
}
static my_calculate_t s_cal = cal_sum;
static int test2_cal (int a, int b)
{
    int result = 0;
    if(s_cal) {
        result = s_cal(a ,b);
        printf("result=%d\r\n", result);
    }
    return result;
}
void app_main(void)
{
    printf("init done\r\n");
    int m = 10, n = 1, ret;
    ret = test2_cal(m, n);
}

上述程序中 s_cal 的值為 cal_sum()函數(shù) cal_sum()就是一個(gè)回調(diào)函數(shù);即當(dāng)前要執(zhí)行的運(yùn)算為 cal_sum 定義的加法運(yùn)算。

當(dāng)前程序的輸出結(jié)果:

init done
now is sum
result=11

也可以改變 s_cal 的值為 cal_sub,cal_mul,它們分別對應(yīng)減法、乘法運(yùn)算。讀者可自行賦值進(jìn)行測試。
 

小結(jié):從上述測試,我們不難理解,僅僅通過更改一個(gè) s_cal函數(shù)指針的值分別指向cal_sum,cal_sub,cal_mul就可以實(shí)現(xiàn)整個(gè)程序運(yùn)行不同的運(yùn)算。運(yùn)算的接口被統(tǒng)一為 test2_cal(),它具備了執(zhí)行多種運(yùn)算的功能(通過更改s_cal函數(shù)指針的值指定其功能)。另外,從該示例中,對于回調(diào)函數(shù),我們還認(rèn)識(shí)到它往往具有一個(gè)外殼,如本例中的 test2_cal()就是外殼,和一個(gè)核心,即函數(shù)指針,如本例中的 s_cal函數(shù)指針。

回調(diào)對于編寫庫文件有很大的好處,比如我們要實(shí)現(xiàn)一個(gè)加法,但加法分很多種:整數(shù)的加法、字符串的加法、指針的加法等等。我們可以定義一個(gè)統(tǒng)一的 add(),并在 add()中定義一個(gè)函數(shù)指針s_add,通過更改s_add所指的函數(shù),來適應(yīng)多種數(shù)據(jù)類型的加法。這在C++ 中被稱為“多態(tài)”,即根據(jù)輸入的數(shù)據(jù)類型,調(diào)用符合該數(shù)據(jù)類型運(yùn)算的函數(shù)。

同樣的,在編寫驅(qū)動(dòng)程序時(shí),由于不同的設(shè)備具備不同的特性,初始化時(shí)的內(nèi)容可能不一樣。使用回調(diào)函數(shù),可以通過改變對應(yīng)的函數(shù)指針的值,來指向不同的設(shè)備的初始化函數(shù),實(shí)現(xiàn)能夠兼容許多設(shè)備的驅(qū)動(dòng)程序。

動(dòng)態(tài)改變回調(diào)函數(shù)的實(shí)現(xiàn)的方法:

如上所示,回調(diào)函數(shù)是通過函數(shù)指針來調(diào)用的。因此想改變回調(diào)函數(shù)的功能,就是研究如何改變函數(shù)指針的值。主要有以下三種方法:

1)編譯時(shí)直接賦值

如上一節(jié)所示的示例,通過對函數(shù)指針 s_cal賦值,可以改變函數(shù) test2_cal()實(shí)際運(yùn)行的計(jì)算。這在編譯時(shí)就知道要將函數(shù)指針 s_cal賦予的值的情況下,可以使用。若在編譯的時(shí)候不知道具體要將 s_cal賦予什么值,或者需要程序運(yùn)行時(shí)動(dòng)態(tài)地改變 s_cal的值,直接賦值的方法無法正常使用。

2)運(yùn)行時(shí)實(shí)現(xiàn)動(dòng)態(tài)注冊

運(yùn)行時(shí),可以通過其他函數(shù)對函數(shù)指針進(jìn)行賦值,在程序運(yùn)行的時(shí)候,動(dòng)態(tài)地改變函數(shù)的行為。

示例:

typedef int (*my_calculate_t)(int a, int b);
static int cal_sum(int a, int b)
{
    printf("now is sum\r\n");
    return a + b;
}
static int cal_sub(int a, int b)
{
    printf("now is sub\r\n");
    return a - b;
}
static int cal_mul(int a, int b)
{
    printf("now is mul\r\n");
    return a * b;
}
static my_calculate_t s_cal = cal_sum;
static int test2_cal (int a, int b)
{
    int result = 0;
    if(s_cal) {
        result = s_cal(a ,b);
        printf("result=%d\r\n", result);
    }
    return result;
}
static void my_cal_calculate_register(my_calculate_t cal)
{
    s_cal = cal;
}
static void my_cal_calculate_unregister(void)
{
    s_cal = NULL;
}
void app_main(void)
{
    printf("init done\r\n");
    int m = 10, n = 2, ret;
    ret = test2_cal(m, n);
    my_cal_calculate_register(cal_sub);
    ret = test2_cal(m, n);
    my_cal_calculate_unregister();
    my_cal_calculate_register(cal_mul);
    ret = test2_cal(m, n);
    my_cal_calculate_unregister();
}

運(yùn)行結(jié)果:

init done
now is sum
result=12
now is sub
result=8
now is mul
result=20

小結(jié):上述程序通過函數(shù) my_cal_calculate_register()動(dòng)態(tài)地改變函數(shù)指針s_cal的值,從而實(shí)現(xiàn)在函數(shù)中動(dòng)態(tài)地改變test2_cal功能的目的。一些庫文件的源代碼是不開放的,因此,一些庫中使用這種通過動(dòng)態(tài)注冊函數(shù)的方法來動(dòng)態(tài)地指定庫函數(shù)實(shí)際功能。

3)作為函數(shù)參數(shù)傳遞到指定的函數(shù)內(nèi)

typedef int (*my_calculate_t)(int a, int b);
static int cal_sum(int a, int b)
{
    printf("now is sum\r\n");
    return a + b;
}
static int cal_sub(int a, int b)
{
    printf("now is sub\r\n");
    return a - b;
}
static int cal_mul(int a, int b)
{
    printf("now is mul\r\n");
    return a * b;
}
static int test1_cal (my_calculate_t actual_cal, int a, int b)
{
    int result = 0;
    result = actual_cal(a ,b);
    printf("result=%d\r\n", result);
    return result;
}
void app_main(void)
{
    printf("init done\r\n");
    int m = 10, n = 2, ret;
    ret = test1_cal(cal_sum, m, n);
    ret = test1_cal(cal_sub, m, n);
    ret = test1_cal(cal_mul, m, n);
}

運(yùn)行結(jié)果:

init done
now is sum
result=12
now is sub
result=8
now is mul
result=20

小結(jié):上面的示例在調(diào)用 test1_cal() 時(shí),通過傳遞要運(yùn)行的運(yùn)算函數(shù),實(shí)現(xiàn)同一個(gè)函數(shù)test1_cal執(zhí)行多個(gè)功能。同名函數(shù)傳遞不同參數(shù)執(zhí)行不同的功能,也是增強(qiáng)函數(shù)兼容性的常見方法。

總結(jié)

本篇文章重點(diǎn)簡述了回調(diào)、回調(diào)函數(shù)的概念。本質(zhì)上,回調(diào)函數(shù)是 C 語言中 函數(shù)指針 的一種用法。回調(diào)函數(shù)用于在統(tǒng)一的接口內(nèi),實(shí)現(xiàn)可以動(dòng)態(tài)地改變函數(shù)的功能。

回調(diào)函數(shù)的實(shí)現(xiàn)至少需要兩個(gè)函數(shù),一個(gè)是外殼,一個(gè)是可以通過函數(shù)指針指定實(shí)際的被執(zhí)行的函數(shù)。

動(dòng)態(tài)改變回調(diào)函數(shù)的實(shí)現(xiàn)的方法主要有三種:

  • 編譯時(shí)直接賦值
  • 運(yùn)行時(shí)實(shí)現(xiàn)動(dòng)態(tài)注冊
  • 作為函數(shù)參數(shù)傳遞到指定的函數(shù)內(nèi)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!     

相關(guān)文章

最新評論