函数指针与回调函数


简介:

在前面我们已经讲过了函数,如何声明函数,如何定义函数,如何调用函数,而且知道了函数名就是函数的地址,那么是否可以用指针来存储函数地址呢?答案是可以的。使用指针来存储函数的地址就是这节的主要内容。

函数指针:

就是存储函数地址的指针,就是指向函数的指针,就是指针存储的值是函数地址,我们可以通过指针可以调用函数。

我们先来定义一个简单的函数:

上面三个步骤就是我们在学习函数的时候必须要做的,只有通过以上三步我们才算定义了一个完整的函数。

如何定义一个函数指针呢?前面我们定义其他类型的指针的格式是 类型 * 指针名 = 一个地址,比如:

也就是说如果我们要定义什么类型的指针就得知道什么类型,那么函数的类型怎么确定呢?函数的类型就是函数的声明把函数名去掉即可,比如上面的函数的类型就是:

我们再来声明一个有参数和返回值的函数:

上面函数的类型依旧是把函数名去掉即可:

既然我们知道了函数的类型那么函数指针的类型就是在后面加个 * 即可,是不是这样呢?

上面这么定义是错误的,绝对是错误的,很多初学者都这样去做,总觉得就应该这样,其实函数指针的类型的定义正好比较特殊,它是这样的:

我们定义函数指针只需在 * 后面加个指针名称即可,也就是下面这样:

如果我们要给 p 赋值的话,我们就应该定义一个返回值类型为 int ,两个参数为 int 的函数:

经过上面的赋值,我们就可以使用 p 来代表函数:

输出结果为:11

通过上面的指针函数来使用函数,一般不是函数的主要用法,我们使用函数指针主要是用来实现函数的回调,通过把函数作为参数来使用,接下来我们来看如何使用函数回调

函数回调:

函数回调的本质就是让函数指针作为函数参数,函数调用时传入函数地址,也就是函数名即可。

我们什么时候使用回调函数呢?咱们先举个例子,比如现在小明现在作业有个题不会做,于是给小红打电话说:我现在作业有个题不会做,你能帮我做下吗?然后把答案告诉我?小红听到后觉得这个题也不是立刻能做出来的,所以跟小明说我做完之后告诉你。这个做完之后告诉小明就是函数的回调,如何告诉小明,小红必须有小明的联系方式,这个联系方式就是回调函数。接下来我们用代码来实现:

小明需要把联系方式留给小红,而且还得得到答案,因此需要个参数来保存答案:

小红这边得拿到小明的联系方式,需要用函数指针来存储这个方法:

上面的回调有人会问为什么我们不能直接 tellXiaoMing 方法中直接调用 contactMethod 函数呢?因为小红如果用函数指针作为参数的时候,不仅可以存储小明的联系方式,还可以存储小军的联系方式,这样的话我这边的代码就不用修改了,你只需要传入不同的参数就行了,因此这样的设计代码重用性很高,灵活性很大。

函数回调的整个过程就是上面这样,这里有个主要特点就是当我们使用回调的时候,一般用在一个方法需要等待操作的时候,比如上面的小红要等到答案做出来的时候才通知小明,不如当小明问小红时,小红直接能给出答案,就没必要有回调了,那执行顺序就是:

imge

回调的顺序是:

imge

上面的小红做题是个等待操作,比较耗时,小明也不能一直拿着电话等待,所以只有小红做出来之后,再把电话打回去才能告诉小明答案。

因此函数回调有两个主要特征:

  • 函数指针作为参数,可以传入不同的函数,因此可以回调不同的函数
  • 函数回调一般使用在需要等待或者耗时操作,或者得在一定时间或者事件触发后回调执行的情况下

我们使用函数回调来实现一个动态排序,我们现在有个学生的结构体,里面包含了姓名,年龄,成绩,我们有个排序学生的方法,但是具体是按照姓名排?还是年龄排?还是成绩排?这个是不确定的,或者一会还会有新需求,因此通过动态排序写好之后,我们只需传入不同的函数即可。

定义学生结构体:

定义比较结果的枚举:

定义成绩,年龄和成绩比较函数:

定义排序函数:

定义结构体数组:

输出排序前的数组,排序和排序后的数组:

总结:

这节主要讲了函数指针,包括函数指针的概念,定义方法,如何使用,还有使用场景等,一定要学会,最后着重讲解了函数回调,函数回调作为一种最基本的程序设计模式,在以后会经常用到,希望大家一定要理解。






链接: http://www.lingxiblogs.com/?p=198#comments





汉字字库存储芯片扩展实验 # 汉字字库存储芯片扩展实验 ## 实验目的 1. 了解汉字字库的存储原理和结构 2. 掌握存储芯片扩展技术 3. 学习如何通过硬件扩展实现大容量汉字字库存储 ## 实验原理 ### 汉字字库存储基础 - 汉字通常采用点阵方式存储(如16×16、24×24、32×32点阵) - 每个汉字需要占用32字节(16×16)到128字节(32×32)不等的存储空间 - 国标GB2312-80包含6763个汉字,需要较大存储容量 ### 存储芯片扩展方法 1. **位扩展**:增加数据总线宽度 2. **字扩展**:增加存储单元数量 3. **混合扩展**:同时进行位扩展和字扩展 ## 实验设备 - 单片机开发板(如STC89C52) - 存储芯片(如27C256、29C040等) - 逻辑门电路芯片(如74HC138、74HC373等) - 示波器、万用表等测试设备 - 连接线若干 ## 实验步骤 ### 1. 单芯片汉字存储实验 1. 连接27C256 EPROM芯片到单片机系统 2. 将16×16点阵汉字字库写入芯片 3. 编写程序读取并显示汉字 ### 2. 存储芯片字扩展实验 1. 使用地址译码器(如74HC138)扩展多片27C256 2. 将完整GB2312字库分布到各芯片中 3. 编写程序实现跨芯片汉字读取 ### 3. 存储芯片位扩展实验 1. 连接两片27C256实现16位数据总线扩展 2. 优化字库存储结构,提高读取速度 3. 测试并比较扩展前后的性能差异 ## 实验代码示例(单片机部分) ```c #include <reg52.h> #include <intrins.h> // 定义存储芯片控制引脚 sbit CE = P2^7; // 片选 sbit OE = P2^6; // 输出使能 sbit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值