学习笔记:浅学C语言回调函数

初学回调函数

    • 函数指针
      • 函数指针的两种定义方式
      • 函数指针里函数的赋值情况
      • 使用函数指针调用函数
      • 函数指针作为函数返回类型
      • 函数指针数组
      • 函数指针的实例
    • 回调函数
      • 回调函数实例
    • 最后

我们先看一下什么是函数指针。再去讲回调函数

函数指针

函数指针的两种定义方式

//方法一
 typedef void (*p_func)(int , int  float); 
 //方法二
 void (*p_func)(int, int, float); 
 /**
 p_func:函数名
 int  int  float:参数类型
*/

这两种方式都是定义了一个指向返回值为 void 类型,参数为 (int, int, float) 的函数指针。第二种方法是为了让函数指针更容易理解,尤其是在复杂的环境下;而对于一般的函数指针,直接用第一种方法就行了。

函数指针里函数的赋值情况

void (*p_func)(int, int, float) = NULL; //定义函数指针

//方法一
 p_func = &func_1;//可有可无的操作符&,这只是显示地说明编译器将去隐式的执行任务
//方法二
 p_func = func_2;

上面两种方法都是合法的,对于第二种方法,编译器会隐式地将 func_2 由 void ()(int, int, float) 类型转换成 void (*)(int, int, float) 类型,因此,这两种方法都行。

使用函数指针调用函数

因为函数指针也是指针,因此可以使用常规的带 * 的方法来调用函数。和函数指针的赋值一样,我们也可以使用两种方法:


/**
#include

int func(int a, int b){
	return a + b
}

int (*ptr)(int, int) = &func //可省操作符 & 
int tes1, test2, test3;
test1 = func(1, 2);
test2 = (ptr)(1, 2);
test3 = (*ptr)(1, 2);
*/


//方法一
int t1 =  p_func(1,2,3.0);
//方法二
int t2 = (*p_func)(1,2,3.0);

//方法一跟平时的函数调用的情况是一样的(注意返回值类型)
//方法二多了一个 * ,这是对p_func执行间接访问操作,把函数指针转换为一个函数名。这样的转换并不是必须的,因为在编译器执行函数调用操作符之前又会把他转换回去。

函数指针作为函数返回类型

void (*func(int, int))(int, int, float)
在这里, func以 (int, int) 为参数,其返回类型为 void (*)(int, int, float) 。

函数指针数组

//方法一
void (*func[5])(int, int, float);
//方法二
typedef void (*func)(int, int, float);
func func_[5];

//上面两种方法都可以用来定义函数指针数组,它们定义了一个元素个数为5类型是 void (*)(int, int, float) 的函数指针数组。

函数指针的实例

#include

int func(int a, int b){
	return a + b;
}

int main(){

	//int (*ptr)(int, int) = &func; //&可有可无

	/**函数指针的定义*/
	//typedef int (*ptr)(int, int);
	int (*ptr)(int, int);
	
	/*函数指针的赋值*/
	ptr = &func;//&可有可无
	int sum1, sum2, sum3;
	
	/**使用函数指针调用函数*/
	sum1 = func(1,2);
	sum2 = (*ptr)(1,2);
	sum3 = (*ptr)(1,2);
	
	printf("数字和为:\nsum1 = %d\n sum2 = %d sum3 = %d", sum1, sum2, sum3);
}

回调函数

维基百科在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。

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

简单的说回调函数是由中间(另一个)函数执行时调用你实现的函数。

回调函数关键在于函数指针的引用,前面把函数指针讲的很明白了,回调函数就直接上代码了

回调函数实例


//
// Created by ubuntu-clion on 2/3/20.
//


#include
#include 

/**函数指针结构体*/
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 Total(float (*p_func)(float, float), float a, float b){
    return (*p_func)(a, b);
}

int main(){
    OP* op = (OP*)malloc(sizeof(OP));
    init_op(op);

    //用函数指针直接输出
    printf("Add_ = %f, Sub_ = %f, Mul_ = %f, Div_ = %f\n\n",
           (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\n\n",
           Total(Add_, 1.3, 2.2),
           Total(Sub_, 1.3, 2.2),
           Total(Mul_, 1.3, 2.2),
           Total(Div_, 1.3, 2.2));
    return 0;
}


本文主要借鉴的大神博文:https://segmentfault.com/a/1190000008293902

最后

本文仅是我对于学习的记录,知识水平有限。若本文有什么问题,望不吝赐教。

你可能感兴趣的:(c语言)