北京华清远见

超干货!| “回调函数”还是“函数回调”?!

作者:华清远见 来源:华清远见
发布日期:2023年08月07日

科普时间到! 不知道有多少人听过 和 这两个词语,是不是弯弯...

科普时间到! 不知道有多少人听过 和 这两个词语,是不是弯弯绕? 华妹今天给大家分享的是 回调函数 。 跟华妹往下看吧~ 1、回调函数的概念 首先声明 “函数回调” 和 “回调函数” 是两个概念。 函数回调是一种机制, 回调函数是一个 函数 。 如:在C语言中不通过函数名,而是通过函数指针调某个函数的方式就叫函数回调。 而在个过程中 “某个函数”就叫做 回调函数 。
举个栗子 void fun_A(void)//回调函数 { printf("AAAAA\n"); } void fun_B(void (*p_fun)(void)) { printf("现在正在执行B函数~~\n"); p_fun();//函数回调 } int main() { fun_B(fun_A); return 0; }
可以看到,在main函数里面,只调用的B函数,但是A函数同样被调用了。 在这个程序里面, 执行p_fun()就叫函数回调,而fun_A函数本身,叫做回调函数。 2、怎么理解回调函数? 比如现在的程序,需要有一个功能,叫做玩游戏。在程序里面,可能有非常多的函数,表示不同的游戏。 而具体要玩什么游戏,按理说应该由使用者,也就是用户来决定。 所以,现在如果我们要提供一个玩游戏的接口,假设叫做play_game. 在这个play_game函数里面肯定不能直接调用某个具体的函数名。 (因为这样用户永远只能玩这一个游戏了) 所以,在调用函数的时候,函数名不应该是一个常量,而应该是一个可变的量。可以用 函数指针 的形式,去表示一个函数名。而函数指针的值,就可以由用户传参,传进来啦。通过这种机制,就可以在程序里面,使用同一个接口,去玩不同的游戏啦。 其实这里的play_game这个接口,就类似于游戏平台,用户可以使用游戏平台玩各种各样的游戏,而具体玩什么,由用户自己决定。 3、回调函数的作用 回调函数的作用主要体现在下面几个方面: 01 异步编程 在异步操作中,回调函数被用作操作完成后的回调处理。例如,当异步请求返回结果时,可以通过回调函数处理和操作返回的数据。 0 2 事件处理 当特定事件发生时,回调函数被调用执行相应的逻辑操作。例如,当用户点击按钮时,可以通过回调函数处理按钮点击事件。 0 3 回调风格的API 某些库或框架提供的API使用回调函数作为参数来实现定制化的功能。通过传递回调函数给这些API,可以在特定事件发生时定制操作。例如,文件读取操作完成后调用回调函数来处理读取到的数据。 04 结果传递 函数回调可以用于将结果传递给其他函数或组件。当一个函数完成某个操作后,可以调用回调函数并将结果作为参数传递给回调函数,以便后续处理。 0 5 扩展性和灵活性 通过使用回调函数,可以将特定的逻辑传递给其他函数,实现代码的重用和模块化。回调函数可以提供灵活的定制选项,使代码更容易扩展和适应不同的场景。 具体的用法如下: 多态、泛型函数、中断机制、signal机制等。 4、高级示例
举个栗子 #include <stdio.h> #include <stdlib.h> #include <string.h> void print_str(void *p) { printf("%c ", *(char *)p); } void print_int(void *p) { printf("%d ", *(int *)p); } void show_arr(void *a, int n, char *type) { int i = 0; for(;i < n;i++) { if(strcmp(type, "char") == 0) print_str(&((char*)a)[i]); else if(strcmp(type, "int") == 0) print_int(&((int *)a)[i]); } printf("\n"); } // 删除大于50的元素 int del_value_gt50(void *a) { return *(int *)a > 50; } // 删除'a' int del_value_a(void *a) { return *(char *)a == 'a'; } int del_arr(void *a, int n, int size, int(*p_fun)(void *)) { char *p = a; char *q = a; int num = 0; for(int i = 0; i < n; i++) { if(!p_fun((void *)p)) { memcpy(q, p, size); q+=size; num++; } p+=size; } return n-num; } int main(int argc, char *argv[]) { char str1[] = "qweasdzxc"; int del_n = del_arr(str1, 9, 1, del_value_a); printf("删除个数:%d\n", del_n); show_arr(str1, 9-del_n, "char"); int arr1[] = {9,4,62,87,3,2,7,4}; del_n = del_arr(arr1, 8, 4, del_value_gt50); printf("删除个数:%d\n", del_n); show_arr(arr1, 8-del_n, "int"); return 0; }

比如,在上述代码中,想要实现一个 的函数,那么具体删除的逻辑可以提前写死,但是预留判断规则给了使用者,所以,del_arr这个函数就需要在内部动态去调用用户的判断算法。 而上述的del_value_gt50,del_value_a,就是回调函数。 明白了吗?期待华妹的下次分享吧,欢迎评论区讨论哦~ 【END】 还有什么知识难点 欢迎给华妹评论、留言华妹等你来撩~

华妹送惊喜优惠福利啦! ↓暑期优享就业 ↓ 购课福利详见海报

往 期 推 荐
超干货!| 嵌入式名企有哪些?你一定要知道! What?!疯批的“恐龙扛狼”背后竟然有这么心酸的真相! 超干货 | 你知道构建跨平台应用的利器是什么吗? 秋招定制 | 繁“华”似锦,共赴“清”凉盛夏之约~
相关资讯
不懂就问:嵌入式比单片机功能更强吗? AI算法工程师会成为下一个“理想型”吗?! 注意!嵌入式工程师的瓶颈有哪些? 【嵌入式软件工程师】都在找的七大架构模式终于找全了! 一文读懂:嵌入式系统中的网络链接如何实现远程监控和控制!
相关课程