回调函数这个是什么鬼?

这是一个同学在微信给我提问的问题。

要搞清楚回调函数,我们首先要搞清楚函数,函数其实就是一个地址,这个地址描述了这个函数在内存中的位置。

但是函数和变量也是一样的,有类型,对变量来说,变量会分成各种类型,对函数来说也是一样,函数会有参数和返回值,不同的参数和返回值就描述了不同的函数。

那回调函数呢?

回调函数其实是一个连锁反应,比如你小孩生病了,这会导致你老婆可能不开心,你老婆不开心了,会连锁反应到你也会不开心。

不开心这个信心从你老婆传递到了你身上,你小孩就起到了函数调用的作用。

我们可以写个简单的代码

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>void func(void *f(int),int parm)
{f(parm);
}void call_back(int parm)
{printf("%s(),LINE=%d,args=%d\n",__FUNCTION__,__LINE__,parm);
}int main(void)
{func(call_back,123);return 0;
}

代码运行

$main
call_back(),LINE=12,args=123

从项目角度上看,callback是一个人实现,然后func里面会是另一个人实现,我们在main里面会把回调的指针注册给func,等某个时机成熟的时候,func就会调用这个指针来做它想做的事情。

但是从C语言和计算机角度出发,函数无非就是一个地址,我们传递的是一个地址,后面我们只是用了这个地址来做了我们想做的事情。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>typedef void (*type_func)(int);void func(u_int64_t* ptr,int parm)
{((type_func)ptr)(parm);
}void call_back(int parm)
{printf("%s(),LINE=%d,args=%d\n",__FUNCTION__,__LINE__,parm);
}int main(void)
{func((u_int64_t*)call_back,123);return 0;
}

这段代码里面的信息就会比较多了,一个是用了typedef来修饰一个函数指针的类型,然后我们在传call_back的时候,强制让它变成了一个地址,之后拿到这个地址后,再让它变成一个函数。

写这个demo的意思就是想让大家知道,函数名,其实不过是一个地址,但是,地址只是单纯的地址,没有多的含义,所以我们需要给地址加上类型,这才是有意义的。

一个人是没有意义的,一个人做的事情,才会让这个人的人生有意义。

$gcc -o main *.c -lm
$main
call_back(),LINE=14,args=123

10cd815b610d408349d349624223433a.png

最后,如果觉得不错,大家顺手点个赞,转发就是对我最大的鼓励和支持!

1a51b682d4acd712938ac3a92f8c6021.png

长按识别二维码关注公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个整数转换成字符串(C/C++自己写的算法)

自己写的一个算法&#xff1a;将一个int型数转换为string char *itoa(int num, char *str){assert(NULL ! str);int i1, j0;if (num < 0){str[j]-;num (-1)*num;}if (0 num){str[j] 0;str[j] \0;return str; }while (! (num/i < 10)){i i*10;}while (num > 0){st…

mysql模糊查询与预编译_mysql预编译模糊查询恶心了我一天的时间,终于弄好了。但是还有一点不明白。如下:...

不用这么麻烦&#xff0c;你可以定义个boolean的变量&#xff0c;用来记录传参是不是description&#xff0c;如果是&#xff0c;在paramList的循环里做模糊拼接&#xff0c;不是&#xff0c;就不用boolean descFlagfalse; //标记传来的参数是否为description&#xff0c;为后面…

小米12比我的小米10还便宜

昨天晚上&#xff0c;小米发布会发布了新的小米12手机&#xff0c;价格很亲民&#xff0c;比我两年前买的小米10还便宜。这还不算&#xff0c;小米12比小米10还更好看。小米在尝试曲面屏之后&#xff0c;终于觉得曲面屏不再是一个可以用来炫耀的卖点了。我自己的小米10曲面屏&a…

庆祝51CTO六周年:资源牛人有奖比拼,生日当天疯狂送豆!(已结束)

2011年8月15日&#xff0c;是51CTO成立6周年的日子。为庆祝这一盛典&#xff0c;特推出此活动。一、活动时间&#xff1a;2011年8月5日——2011年8月25日 24:00二、活动奖项及规则&#xff1a;1、资源牛人金奖&#xff1a;入围资源牛人排行榜前十名的Down友已经产生&#xff0c…

Centos7:mysql5.6安装,配置及使用(RPM方式)

1.首先安装好jdk环境,本机所用环境为jdk1.8 2.卸载MariaDB(Centos7自带)与Mysql 2.1卸载:MariaDB #rpm -qa | grep -i mariadb //查询安装的MariaDB#rpm -e --nodeps 查到软件名 //卸载相关MariaDB的所有软件#find / -name mariadb#whereis mariadb //查找是否有相关配置目录及…

判断一个单链表中是否存在环

#判断一个单链表中是否存在 环。 #设置两个指针(fast, slow)&#xff0c;初始值都指向头&#xff0c;slow每次前进1步&#xff0c;fast每次前进2步&#xff0c; 大概的思路如下&#xff1a; 如果链表存在环&#xff0c;则fast必定先进入环&#xff0c;而slow后进入环&#xff…

mysql3.5 所有表_mysql学习笔记3.5

紧接着笔记3的训练介绍一个对于我来说的比较难的难点&#xff01;&#xff01;&#xff01;&#xff01;select * from sc;select student.sno,sname,avg(grade) as平均分fromstudent,scwhere student.snosc.snogroup bystudent.snohaving avg(grade)>90/*这一个条件我竟然忘…

CPU上电后加载程序的流程 | 基于RK3399

芯片上电解复位之后执行的第一段程序&#xff0c;在芯片中称之为Bootrom loader。这部分程序在芯片制造过程中固化到其内部的ROM空间&#xff0c;具备只读属性&#xff0c;在实际使用过程中无法修改这部分内容&#xff0c;这部分程序的知识产权也仅归属于芯片公司所有。其实&am…

IPv6与IPv4的区别

Technorati 标签: Hank--network porter■第一个就不说哈&#xff0c;32bit直接升级到128bit了。 从2的32次方升级到2的128次方了&#xff0c;地球上的每一粒沙子都可以分到一个IP地址。这个是IPv6最拉风的地方. ■在IPv6中&#xff0c;路由器不能用自动配置机制来配置接口&…

前端安全系列(一):如何防止XSS攻击?

前端安全 随着互联网的高速发展&#xff0c;信息安全问题已经成为企业最为关注的焦点之一&#xff0c;而前端又是引发企业安全问题的高危据点。在移动互联网时代&#xff0c;前端人员除了传统的 XSS、CSRF 等安全问题之外&#xff0c;又时常遭遇网络劫持、非法调用 Hybrid API …

判断一个链表是否为循环单链表

判断一个链表是否为循环单链表&#xff1a; #设置两个指针(fast, slow)&#xff0c;slow步长为1&#xff0c;fast步长为2&#xff0c; 大概的思路如下&#xff1a; 如果链表为循环单链表&#xff0c;则fast与slow必定相遇。 如果链表不为循环单链表&#xff0c;则fast必定先指…

在腾讯的这半年

晚上和同事聚餐后&#xff0c;我和李总坐车回公司&#xff0c;李总在电话里面和大家开会&#xff0c;然后说着各种让大家帮忙的话&#xff0c;我看着窗外密密麻麻的车辆——想着&#xff0c;这一年又要过去了。我是有总结的习惯的&#xff0c;不管是做事情还是生活&#xff0c;…

mysql数据删除后无法恢复数据恢复_Mysql数据库delete删除后数据恢复报告

原标题&#xff1a;Mysql数据库delete删除后数据恢复报告数据库环境部署与故障原因&#xff1a;本次恢复的数据库安装在客户本地服务器上&#xff0c;服务器操作系统为windows2008 r2 。在当前环境内安装有mysql5.6单实例&#xff0c;引擎类型为innodb&#xff0c;表内数据存储…

HDU 下沙的沙子有几粒

题目网址&#xff1a; http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid2&sectionid3&problemid9 分析&#xff0c;这题其实是H和D的组合排列问题&#xff0c;只不过要考虑期间累计的H和D的数量关系。 用DP来做&#xff0c;可以推导出&#xff1a; dp…

一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针

输入一个单向链表&#xff0c;输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针 typedef struct _node_t {struct _node_t *next;int data; }Node;Node *list_k_node(Node * head, int k) {Node *phead, *pkhead;if (NULL head || (0 > k)){return NULL;}fo…

Linux之yum安装lamp环境

参照链接: http://www.jb51.net/os/RedHat/9939.html http://pjhfjy.blog.163.com/blog/static/47876996200963025757122/ http://oldleader.blog.163.com/blog/static/170861343201102085947386/ http://arqiang86.blog.163.com/blog/static/1092594200871211548121/

倒计时跳转页面

<h3>目标&#xff1a;百度<span idt></span></h3> <script>var i5;var tdocument.getElementById(t);t.innerHTML i秒后跳转;setInterval(function () {t.innerHTML--i秒后跳转;if(i0){location.hrefbaidu.com}},1000) </script> 转载于:h…

Linux启动流程 | kernel执行第一个init应用程序的实现原理

1. 概述Linux系统启动过程中通过init_task创建0号idle进程。然后通过kernel_thread创建1号init进程。创建该进程时通过系统调用&#xff0c;在内核空间执行用户空间的/sbin/init程序&#xff0c;通过该程序产生出shell&#xff0c;并依赖init衍生出其他进程。通过top命令查看当…

m进制转换为n进制

m进制转换为n进制 void m2n(unsigned char *dest, unsigned int n, unsigned char *src, unsigned int m) {unsigned char ch, *p dest - 1;unsigned int i 0;if ((NULL dest) || (NULL src)){return ;}if ((m < 2 || m > 36) || (n < 2 || n > 36)){return ;}…