回调函数是嘛东西

编程分为两类:系统编程(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`传入不同的回调函数,它的表现也不同,这就是回调机制的优势所在。值得一提的是,上面的第三个回调函数是一个匿名函数。

原文地址:https://www.cnblogs.com/strive-sun/p/15351600.html