小白学习回调函数

见到有一篇文章讲的挺好的回调函数
下面是内容:

回调函数

回调函数是一个时时听到的概念,比如在windows API编程时遇到的WinProc函数,就是我们编写而由操作系统调用的函数。现在,我们需要慢慢又详细的记录一下这个问题。

库与使用者的问题

在开始之前,首先我们想像这样一个情景,一个大型软件公司开发一套软件库提供给用户使用。在这句话中,出现两个对立面,一个是软件公司,一个是用户。显然,软件公司实力很强大,他们强大的地方在于他们很聪明。请看下图:
在这里插入图片描述
库开发者是提供方,他们不知道用户想做什么,库开发者对用户的信息是未知的,因为两边的人谁也没见过谁,就像一个人在美国一个人在中国。他们聪明的地方就在于即使不知道用户怎么操作,他们也可以用一种通用的方法来解决用户的问题。换句话说,库开发方不管用户怎么折腾变化,他都能适应。这就是问题的神奇之处,当然,为了达到这种效果,必须有一种规则来约束。

规则

现在来说规则,规则比较好理解,就是两方达成的约束。比如甲和乙两个人,甲对乙说,你只要提供给我一个塑料球,我都能给它涂上颜色。这里的约束是塑料球,(当然,为了简化问题这里的约束还是比较泛泛而不严谨的),这个时候如果乙给他一个水晶球,或者给他一辆汽车都不行,因为已经超越了约束。所以说,库开发者能适应用户的各种变化就在于他也给了用户一定的约束,是在约束之下的适应,这也是不言自明的。

代码之下无秘密

下面一段代码极好的解释了上述问题:

#include <stdio.h>

typedef int student_id;
typedef int student_age;
typedef struct _Student{
    student_id id;
    student_age age;
}Student;

//类型重定义:函数指针类型
typedef bool (*pFun)(Student, Student);


//-----------------------------------------------
//冒泡排序法:能够按AGE或ID排序,用同一个函数实现
//-----------------------------------------------
void sort(Student stu[],const int num,pFun fun)
{
    Student temp;
    
    for(int i = 0; i < num; ++i)
  {
        for(int j = 0; j < num - i -1; ++j)
        {
            if((*fun)(stu[j],stu[j+1]))
            {
                temp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = temp;
            }
        }
    }
}

//-----------------------------------------------
//回调函数:比较年龄
//-----------------------------------------------
bool CompareAge(Student stu1,Student stu2)
{
    //更改从大到小还是从小到大的顺序,只需反一下。
    if(stu1.age < stu2.age)
        return true;
    return false;
}
//-----------------------------------------------
//回调函数:比较id
//-----------------------------------------------
bool CompareId(Student stu1,Student stu2)
{
    //更改从大到小还是从小到大的顺序,只需反一下。
    if(stu1.id < stu2.id)
        return true;
    return false;
}

int main()
{
    Student stu[] = {
    {1103,24},
    {1102,23},
    {1104,22},
    {1107,25},
    {1105,21}};
    
    pFun fun = CompareAge;
    int size = sizeof(stu)/sizeof(Student);
    
    sort(stu,size,fun);
    
    for(int i = 0; i < size; ++i){
        printf("%d %d\n",stu[i].id,stu[i].age);
    }
    
    return 0;
}

通过代码,我们必须分辨出哪个是库提供方,哪个是用户:
在这里插入图片描述
sort(…)方法是库开者提供的,只是因为模拟问题所以把它写在一个文件中了,我们可以假想它存放在某个静态库lib里面,这样就和它有了界限。

库开发者提供方法sort(…)供我们调用,形参里面还包括一个函数指针,就是调用用户自己写的函数,也即回调函数。所以它提供了规则,也就是说这个回调函数的形参是什么,返回值又是什么,假如用户对于这个回调函数的形参和返回值啥都不知道,随意写了一个函数放进去,sort方法能接受吗?显然是不行的。

那么用户怎么知道回调函数的形参和返回值等信息呢?库开发方会告知,或者在它的文档里面会有说明,就像在windows API开发窗口程序时提供的WinProc() 函数一样,里面的形参必须一模一样。(这个地方会牵涉到接口)

什么是回?

根据上面的代码,我们知道,库开发方提供了一个方法,然后形参又带有一个函数指针,等着用户去写然后拿来调用,并在其实现中调用了这个函数。站在库开发方的立场,我们可以总结为一句话:库开发方调用了用户的函数(回调函数)。

现在,我们把视角移到回调函数的立场上来看,它被调用了。但同时它也有参数,且传进来的参数是库开发方提供的数据,这里我们又可以总结一句话:回调函数调用了库开发方的数据。

这就是“回”的意思,你调我我也调用你,双方互相调用。在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值