zoukankan      html  css  js  c++  java
  • 回调函数是嘛东西

    编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application programming interface,应用编程接口),以供应用程序员使用。所以在抽象层的图示里,库位于应用的底下。

    当程序跑起来时,一般情况下,应用程序(application program)会时常通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)

    百度百科介绍: 回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。 回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

     简单的例子:

    #include <stdio.h>
    #include <stdlib.h>
    
    /****************************************
     * 函数指针结构体
     ***************************************/
    typedef struct _OP {
      float (*p_add)(float, float);
      float (*p_sub)(float, float);
      float (*p_mul)(float, float);
      float (*p_div)(float, float);
    } OP;
    
    /****************************************
     * 加减乘除函数
     ***************************************/
    float ADD(float a, float b) { return a + b; }
    
    float SUB(float a, float b) { return a - b; }
    
    float MUL(float a, float b) { return a * b; }
    
    float DIV(float a, float b) { return a / b; }
    
    /****************************************
     * 初始化函数指针
     ***************************************/
    void init_op(OP *op) {
      op->p_add = ADD;
      op->p_sub = SUB;
      op->p_mul = &MUL;
      op->p_div = &DIV;
    }
    
    /****************************************
     * 库函数
     ***************************************/
    float add_sub_mul_div(float a, float b, float (*op_func)(float, float)) {
      return (*op_func)(a, b);
    }
    
    int main(int argc, char *argv[]) {
      OP *op = (OP *)malloc(sizeof(OP));
      init_op(op);
    
      /* 直接使用函数指针调用函数 */
      printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f
    ", (op->p_add)(1.3, 2.2),
             (*op->p_sub)(1.3, 2.2), (op->p_mul)(1.3, 2.2), (*op->p_div)(1.3, 2.2));
    
      /* 调用回调函数 */
      printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f
    ",
             add_sub_mul_div(1.3, 2.2, ADD), add_sub_mul_div(1.3, 2.2, SUB),
             add_sub_mul_div(1.3, 2.2, MUL), add_sub_mul_div(1.3, 2.2, DIV));
    
      return 0;
    }
    

    起始项目: 

    int main(int argc, char *argv[]) {
      OP *op = (OP *)malloc(sizeof(OP));
      init_op(op);
    ...

    中间函数:

    float add_sub_mul_div(float a, float b, float (*op_func)(float, float)) {
      return (*op_func)(a, b);
    }

    回调函数:

    float ADD(float a, float b) { return a + b; }
    
    float SUB(float a, float b) { return a - b; }
    
    float MUL(float a, float b) { return a * b; }
    
    float DIV(float a, float b) { return a / b; }

      

    相关文章:


    另一个例子:

    Python写成的回调的简单示例:

    `even.py`
    #回调函数1
    #生成一个2k形式的偶数
    def double(x):
        return x * 2
        
    #回调函数2
    #生成一个4k形式的偶数
    def quadruple(x):
        return x * 4

    `callback_demo.py`
    from even import *
    
    #中间函数
    #接受一个生成偶数的函数作为参数
    #返回一个奇数
    def getOddNumber(k, getEvenNumber):
        return 1 + getEvenNumber(k)
        
    #起始函数,这里是程序的主函数
    def main():    
        k = 1
        #当需要生成一个2k+1形式的奇数时
        i = getOddNumber(k, double)
        print(i)
        #当需要一个4k+1形式的奇数时
        i = getOddNumber(k, quadruple)
        print(i)
        #当需要一个8k+1形式的奇数时
        i = getOddNumber(k, lambda x: x * 8)
        print(i)
        
    if __name__ == "__main__":
        main()
    运行`callback_demp.py`,输出如下:
    3
    5
    9

    上面的代码里,给`getOddNumber`传入不同的回调函数,它的表现也不同,这就是回调机制的优势所在。值得一提的是,上面的第三个回调函数是一个匿名函数。

  • 相关阅读:
    #Leetcode# 541. Reverse String II
    PAT 甲级 1030 Travel Plan
    PAT 甲级 1029 Median
    bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊
    jzoj 4243. 【五校联考6day1】c
    2019.02.23【NOIP提高组】模拟 A 组 总结
    【GDOI2013模拟1】病毒传播
    【GDOI2013模拟1】最短路
    【GDOI2013模拟1】删数字
    数列分块入门 6 总结
  • 原文地址:https://www.cnblogs.com/strive-sun/p/15351600.html
Copyright © 2011-2022 走看看