广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言中回调函数的含义与使用场景详解
  • 477
分享到

C语言中回调函数的含义与使用场景详解

2024-04-02 19:04:59 477人浏览 泡泡鱼
摘要

目录举例动态改变回调函数的实现的方法:1)编译时直接赋值2)运行时实现动态注册3)作为函数参数传递到指定的函数内总结举例 在下述程序中函数 test2_cal() 中调用&

举例

在下述程序中函数 test2_cal() 中调用 函数指针 s_cal 指定的函数执行数值的计算。则 s_cal 指定的那些函数就可以看作一个回调函数。

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()函数 cal_sum()就是一个回调函数;即当前要执行的运算为 cal_sum 定义的加法运算。

当前程序的输出结果:

init done
now is sum
result=11

也可以改变 s_cal 的值为 cal_sub,cal_mul,它们分别对应减法、乘法运算。读者可自行赋值进行测试
 

小结:从上述测试,我们不难理解,仅仅通过更改一个 s_cal函数指针的值分别指向cal_sumcal_sub,cal_mul就可以实现整个程序运行不同的运算。运算的接口被统一为 test2_cal(),它具备了执行多种运算的功能(通过更改s_cal函数指针的值指定其功能)。另外,从该示例中,对于回调函数,我们还认识到它往往具有一个外壳,如本例中的 test2_cal()就是外壳,和一个核心,即函数指针,如本例中的 s_cal函数指针。

回调对于编写库文件有很大的好处,比如我们要实现一个加法,但加法分很多种:整数的加法、字符串的加法、指针的加法等等。我们可以定义一个统一的 add(),并在 add()中定义一个函数指针s_add,通过更改s_add所指的函数,来适应多种数据类型的加法。这在c++ 中被称为“多态”,即根据输入的数据类型,调用符合该数据类型运算的函数。

同样的,在编写驱动程序时,由于不同的设备具备不同的特性,初始化时的内容可能不一样。使用回调函数,可以通过改变对应的函数指针的值,来指向不同的设备的初始化函数,实现能够兼容许多设备的驱动程序。

动态改变回调函数的实现的方法:

如上所示,回调函数是通过函数指针来调用的。因此想改变回调函数的功能,就是研究如何改变函数指针的值。主要有以下三种方法:

1)编译时直接赋值

如上一节所示的示例,通过对函数指针 s_cal赋值,可以改变函数 test2_cal()实际运行的计算。这在编译时就知道要将函数指针 s_cal赋予的值的情况下,可以使用。若在编译的时候不知道具体要将 s_cal赋予什么值,或者需要程序运行时动态地改变 s_cal的值,直接赋值的方法无法正常使用。

2)运行时实现动态注册

运行时,可以通过其他函数对函数指针进行赋值,在程序运行的时候,动态地改变函数的行为。

示例:

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();
}

运行结果:

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

小结:上述程序通过函数 my_cal_calculate_register()动态地改变函数指针s_cal的值,从而实现在函数中动态地改变test2_cal功能的目的。一些库文件的源代码是不开放的,因此,一些库中使用这种通过动态注册函数的方法来动态地指定库函数实际功能。

3)作为函数参数传递到指定的函数内

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);
}

运行结果:

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

小结:上面的示例在调用 test1_cal() 时,通过传递要运行的运算函数,实现同一个函数test1_cal执行多个功能。同名函数传递不同参数执行不同的功能,也是增强函数兼容性的常见方法。

总结

本篇文章重点简述了回调、回调函数的概念。本质上,回调函数是 C 语言中 函数指针 的一种用法。回调函数用于在统一的接口内,实现可以动态地改变函数的功能。

回调函数的实现至少需要两个函数,一个是外壳,一个是可以通过函数指针指定实际的被执行的函数。

动态改变回调函数的实现的方法主要有三种:

  • 编译时直接赋值
  • 运行时实现动态注册
  • 作为函数参数传递到指定的函数内

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!     

--结束END--

本文标题: C语言中回调函数的含义与使用场景详解

本文链接: https://www.lsjlt.com/news/144069.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言中回调函数的含义与使用场景详解
    目录举例动态改变回调函数的实现的方法:1)编译时直接赋值2)运行时实现动态注册3)作为函数参数传递到指定的函数内总结举例 在下述程序中函数 test2_cal() 中调用&...
    99+
    2022-11-13
  • C语言中回调函数的含义与使用场景详解(2)
    目录详解C语言中回调函数的含义与使用场景(2)使用场景一(重定义):使用场景二(扩展函数功能):使用场景三(分层):总结详解C语言中回调函数的含义与使用场景(2) 引言:在上一篇文章...
    99+
    2022-11-13
  • C语言中回调函数的使用详情
    目录1.程序架构2.回调函数的作用3.掌握回调函数的程序编写4.回调函数在产品中的应用下文将学习到; 程序架构的核心理念和需求掌握回调函数的作用掌握回调函数的程序编写掌握回调函数在产...
    99+
    2022-11-13
  • C语言中回调函数和qsort函数的用法详解
    目录回调函数指向函数指针数组的指针qsort(qulick sort)-库函数回调函数 通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调...
    99+
    2022-11-13
  • c语言中的回调函数怎么使用
    这篇文章主要讲解了“c语言中的回调函数怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“c语言中的回调函数怎么使用”吧!一、通过这节课程你能掌握以下知识...
    99+
    2022-10-19
  • C语言中scanf与scanf_s函数的使用详解
    目录1.scanf_s(是vs提供的函数)2.scanf(标准的库函数)3.总结1.scanf_s(是vs提供的函数) a.代码1 int main() { char a = ...
    99+
    2022-11-12
  • C语言的回调函数怎么使用
    本篇内容主要讲解“C语言的回调函数怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言的回调函数怎么使用”吧!对指针的应用是C语言编程的精髓所在,而回调函数就是C语言里面对函数指针的高级...
    99+
    2023-06-17
  • C语言的回调函数如何使用
    这篇“C语言的回调函数如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言的回调函数如何使用”文章吧。1.程序架构一...
    99+
    2023-06-29
  • C语言详解函数与指针的使用
    目录一、函数类型二、函数指针三、回调函数四、小结一、函数类型 C 语言中的函数有自己特定的类型 函数的类型由返回值,参数类型和参数个数共同决定,如 int add(int i, in...
    99+
    2022-11-13
  • c语言中回调函数的使用以及实际作用详析
    目录前言一、通过这节课程你能掌握以下知识:二、程序架构的核心理念和需求三、回调函数的作用1.输出型2.输入型四、掌握回调函数的程序编写总结前言 今天给大家讲一下芯片/模块厂家写SDK...
    99+
    2022-11-12
  • GO语言中回调函数的使用
    目录0.前言1.使用2.几个例子2.1 异步访问URL2.2 Sort.Slice函数2.3 简易计算器0.前言 回调函数是一种在编程中常见的技术,通常在异步编程中使用。简单来说,回...
    99+
    2023-03-06
    GO语言回调函数 GO 回调
  • c语言函数的定义与调用方法是什么
    C语言函数的定义和调用方法如下:1. 函数的定义:在C语言中,函数的定义包括函数的返回类型、函数名、参数列表和函数体。函数的定义一般...
    99+
    2023-08-18
    c语言
  • C语言详解select函数的使用
    目录selectselect API介绍select 代码编译运行select和poll缺点select select API介绍 主旨思想: 首先要构造一个关于文件描述符的列表,将...
    99+
    2022-11-13
  • C语言中getchar()函数使用详解
    目录一、getchar( ) 函数定义二、函数返回值三、注意区分 getchar 和 scanf四、getchar 的使用实例一、getchar( ) 函数定义 ...
    99+
    2022-12-08
    c语言getchar( ) 函数 getchar( ) 函数 getchar使用
  • Go语言学习之函数的定义与使用详解
    目录1、函数定义2、多值返回3、引用传递4、函数作为实参使用5、匿名函数1、函数定义 函数的定义和java一样,使用{}进行包裹,并且要明确入参类型以及返回类型。 样例代码如下: f...
    99+
    2022-11-13
  • C语言中的内联函数(inline)与宏定义(#define)详细解析
    先简明扼要,说下关键:1、内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样在运行时速度更快。2、内联函数可以调试,而宏定义是不...
    99+
    2022-11-15
    内联函数 宏定义
  • 详解C语言中strcpy函数与memcpy函数的区别与实现
    目录字符串拷贝函数(strcpy)函数原型应用实例缺点内存拷贝函数(memcpy)函数原型应用实例memcpy的模拟实现(my_memcpy)实现样例具体实现字符串拷贝函数(strc...
    99+
    2022-12-29
    C语言 strcpy memcpy区别 C语言 strcpy memcpy实现 C语言 strcpy memcpy
  • C语言库函数qsort的使用详解
    目录一、回调函数二、库函数qsort三、使用qsort排序整型数组四、使用qsort排序结构体1、使用qsort排序结构体中的字符成员2、使用qsort排序结构体中的整型成员五、基于...
    99+
    2022-11-13
  • 详解C++中函数模板的定义与使用
    目录1. 前言2. 初识函数模板2.1 语法2.2 实例化2.3 实参推导3. 重载函数模板1. 前言 什么是函数模板? 理解什么是函数模板,须先搞清楚为什么需要函数模板。 如果现在...
    99+
    2022-11-13
  • GO语言中的回调函数如何使用
    这篇文章主要介绍了GO语言中的回调函数如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇GO语言中的回调函数如何使用文章都会有所收获,下面我们一起来看看吧。0.前言回调函数是一种在编程中常见的技术,通常在异...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作