0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

函数指针和回调函数的使用方法

CHANBAEK 来源:嵌入式之入坑笔记 作者:嵌入式之入坑笔记 2023-04-10 15:08 次阅读

了解开发语言的朋友应该都会对回调函数有所了解,在很多的程序开发语言中都能看到回调的身影。 很多场景下,当某个条件成立以后我们希望代码执行某些指定的部分,这个时候可以考虑使用回调函数的方式,这样做思路更加的清晰,也能使代码结构的逻辑更加清晰,结构更加好。

那回调函数到底是什么呢? 它又是怎么实现的呢?

这是本次想要简单分析的一个主题。

但是在说回调函数之前,我觉得很有必要先说明一下 “函数指针” 这个概念,它是回调函数能够实现的重要基础。

1、函数指针

学习过C语言的伙伴都知道,C语言中的灵魂 — 指针。 可以毫不犹豫地说,要检验你对C语言的掌握程度,那指针绝对是最好的考察方式。 指针的使用和变幻方式,真正的使用起来能让你眼花缭乱。

下面是常见的指针的定义:

int *ptr1;
char *ptr2;
struct std *ptr3; // 结构体指针

那函数指针到底是什么呢?

函数指针:函数指针是指向函数的指针变量。 简单理解是指向函数名的指针变量。

函数指针既然是指向函数的,那么它就可以像函数一样,用于调用函数、传递参数等操作。 函数指针的定义方式如下:

函数返回值类型  (* 指针变量名) (函数参数列表);


“函数返回值类型”:表示该指针变量可以指向具有什么返回值类型的函数;
“函数参数列表”:表示该指针变量可以指向具有什么参数列表的函数。


举例如下:
int (*func1)(void)
int (*func2)(int,char,...)
char (*func3)(int,char,...)
......

从上面的演示可以看到,函数指针的定义就是将一个函数中的 “函数名” 改成“(* 指针变量名)”的方式,从而实现了一个函数指针的定义。

但是这里需要注意的是:“(* 指针变量名)”两端的括号是必须要有的,如果缺少了这对括号,那么这个定义的方式就会变为指针函数。 如下:

int *func1(void)
int *func2(int,char,...)
char *func3(int,char,...)
......


这种就不是函数指针了,而是指针函数。两者差别是很大的。

特别需要需要注意的一点是:指向函数的指针变量没有 ++ 和 -- 运算。

对于函数指针,一般为了方便使用,我们会选择另外的一种定义方式:

typedef  函数返回值类型  (* 指针变量名) (函数参数列表);

比如:

typedef int (*Fun1)(int,...); 
typedef int (*Fun2)(int, int,...); 
typedef void (*Fun3)(void); 
typedef void* (*Fun4)(void*); 
......

2.、函数指针的使用方式

清楚了函数指针是什么东西了之后,那函数指针要怎么使用呢? 看下面的例子:

/* 1.首先定义一个函数 */
int Func(int x);


/* 2.然后定义一个函数指针 */
int (*p) (int x); 


/* 3.将Func函数的首地址赋给指针变量p */
p = Func;
或
p = &Func; 


/* 4.然后使用p调用Func函数 */
(*p) (int x);

因为函数名 Func 代表函数的首地址,所以经过赋值以后,指针变量 p 保存的就是Func的函数入口地址,即 p 就指向函数 Func() 代码的首地址。

为了加深函数指针的使用方式,看下面的一段代码你就明白了。 如下:

#include 


int Max(int, int); //函数声明


int main(void)
{
    int a, b, c;
    int(*p)(int, int); //定义一个函数指针


    p = Max; //把函数Max赋给指针变量p, 使p指向Max函数


    printf("please enter a and b:");
    scanf("%d %d", &a, &b);
    c = (*p)(a, b); //通过函数指针调用Max函数
    printf("a = %d\\nb = %d\\nmax = %d\\n", a, b, c);
    return 0;
}


int Max(int x, int y) //定义Max函数
{
    int z;
    if (x > y) z = x;
    else z = y;


    return z;
}

特别注意的是,因为函数名本身就可以表示该函数地址(指针),因此在获取函数指针时,可以直接用函数名,也可以取函数的地址。

3. 函数指针可以作为函数的参数来使用

函数指针变量本身也是一个变量,也可以作为某个函数的参数进行使用的。 如下:

#include 
#include 


// 定义一个函数指针类型的 FunType
typedef void(*FunType)(int);


void myFun(int x);
void hisFun(int x);
void herFun(int x);
void callFun(FunType fp,int x);


int main()
{
    callFun(myFun,1000);//传入函数指针常量,作为回调函数
    callFun(hisFun,5000);
    callFun(herFun,4700);


    return 0;
}

4、回调函数

前面讲了函数指针,现在终于到了回调函数了。 到这部分,我们就不说太多的废话,直接阐述回调函数是什么,回调函数要怎么使用,一步到位吧!

回调函数:如果一个函数的指针(函数名或地址)作为参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,就说这个指针所指向的函数是一个回调函数。

再简明点说:回调函数不是直接调用该函数进行使用的,而是要通过另外的特定事件或者其他函数进行调用的,才能称作回调函数。 定义一个函数然后直接调用,都不能称为回调函数。

回调函数的定义方式和使用,直接通过下面的例子说明,相信大家一看就会明白。

例程1:

/* 回调函数 */
int Callback(void) 
{
    return 0;
}


int Library(int value,int (*MycallBackFunc)(void))
{
    if(value == 1)
MycallBackFunc();
    else
    return 1;
}




int main() 
{
    Library(1,Callback);    // 返回值为 0
return 0;
}

例程2:

int Callback_1(int a) // 回调函数1
{
    printf("Hello, this is Callback_1: a = %d ", a);
    return 0;
}


int Callback_2(int b) // 回调函数2
{
    printf("Hello, this is Callback_2: b = %d ", b);
    return 0;
}


int Callback_3(int c) // 回调函数3
{
    printf("Hello, this is Callback_3: c = %d ", c);
    return 0;
}


int MyHandle(int x, int (*MyCallback)(int)) 
{
    MyCallback(x);
}


int main()
{
    MyHandle(4, Callback_1);
    MyHandle(5, Callback_2);
    MyHandle(6, Callback_3);


    return 0;
}

从上面的代码可以看出,MyHandle() 函数的参数有一个指针,在 main() 函数里调用MyHandle() 函数的时候,给它传入了函数 Callback_1()、Callback_2()、Callback_3() 的函数名,这时候的函数名就是对应函数的指针,也就是说,回调函数其实就是函数指针的一种用法。

到此,通过上面的函数指针的说明和回调函数的示例代码,估计看到这里的朋友应该都明白了回调函数的使用了吧!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7533

    浏览量

    128814
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70364
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66807
  • 回调函数
    +关注

    关注

    0

    文章

    87

    浏览量

    11456
  • 函数指针
    +关注

    关注

    2

    文章

    53

    浏览量

    3737
收藏 人收藏

    评论

    相关推荐

    函数指针指针函数的概念

    不少朋友会混淆“函数指针”和“指针函数”这两个概念,本文详细介绍一下。
    发表于 03-09 10:49 921次阅读

    一文详解函数指针与回调函数

    函数指针是指向函数指针变量。它允许我们将函数作为参数传递给其他函数或将
    发表于 08-22 10:36 191次阅读

    函数小结

    调用对应的函数)的这个过程就是函数回调过程,被函数称为
    发表于 07-05 01:51

    函数指针指针函数函数总结分享!

    看蓝牙协议栈的时候遇到了函数,之前就没有用过,函数指针函数
    发表于 10-15 19:23

    C 语言函数详解

    (虽然经常吐槽百度搜索...):函数就是一个通过函数指针调用的函数。如果你把
    发表于 04-08 10:36

    为什么说函数可以实现异步操作

    前言在STM32芯片开始从固件库到HAL库迁移后,单片机底层驱动的可移植性越来越好了也越来越像上层应用程序了。因为它把底层的部分硬件相关(寄存器)给屏蔽了。函数
    发表于 08-11 08:18

    ajax方法名使用什么事件,ajax的函数和匿名函数 精选资料分享

    1.什么是js函数一. 函数的作用js代码会至上而下一条线执行下去,但是有时候我们需要等
    发表于 09-01 07:15

    C/C++函数

    C/C++函数首先看一下函数的官方解释:
    发表于 02-11 15:25

    函数指针指针函数定义

    函数指针指针函数,C语言学习中最容易混淆的一些概念,好好学习吧
    发表于 01-11 16:44 0次下载

    C语言指针函数函数指针详细介绍

    C语言指针函数函数指针详细介绍。。。。。。。
    发表于 03-04 15:27 5次下载

    c语言函数指针定义,指针函数函数指针的区别

     往往,我们一提到指针函数函数指针的时候,就有很多人弄不懂。下面就由小编详细为大家介绍C语言中函数指针
    发表于 11-16 15:18 3412次阅读

    理解函数指针函数指针数组、函数指针数组的指针

    理解函数指针函数指针数组、函数指针数组的指针
    的头像 发表于 06-29 15:38 1.4w次阅读
    理解<b class='flag-5'>函数</b><b class='flag-5'>指针</b>、<b class='flag-5'>函数</b><b class='flag-5'>指针</b>数组、<b class='flag-5'>函数</b><b class='flag-5'>指针</b>数组的<b class='flag-5'>指针</b>

    C语言进阶:函数指针的概念和使用方法

    函数指针是指向函数指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数
    发表于 05-02 06:17 5069次阅读

    了解一下函数指针的概念和使用方法

    在讲回调函数之前,我们需要了解函数指针
    的头像 发表于 11-06 10:04 313次阅读
    了解一下<b class='flag-5'>函数</b><b class='flag-5'>指针</b>的概念和<b class='flag-5'>使用方法</b>

    函数指针指针函数是不是一个东西?

    函数指针的本质是指针,就跟整型指针、字符指针一样,函数指针
    的头像 发表于 01-03 16:35 266次阅读
    <b class='flag-5'>函数</b><b class='flag-5'>指针</b>和<b class='flag-5'>指针</b><b class='flag-5'>函数</b>是不是一个东西?