一杯清酒邀明月
天下本无事,庸人扰之而烦耳。
posts - 3121,comments - 209,views - 578万

一、函数指针

函数指针:指向存放函数空间首地址的指针变量。

函数指针的定义方式为:

函数返回值类型 (* 指针变量名) (函数参数列表);

一般为了方便使用,我们会选择 

typedef 函数返回值类型 (* 指针变量名) (函数参数列表);

typedef的功能是定义新的类型。

// 函数指针
type int (*ptrFunc)(int,int);

第一句就是定义了一种 ptrFunc 的类型,并定义这种类型为指向某种函数的指针,这种函数以两个int为参数并返回int类型。后面就可以像使用int,char等变量类型名一样使用 ptrFunc 了。

二、回调函数和注册函数

简单来说,注册函数就是父函数,注册函数就是子函数。父函数可以指定某个子函数去执行。看代码如下:

  这里我们写了4个回调函数,它们的函数签名跟我们之前定义的函数指针一致,但是完成的是不同的功能。下面写一个注册函数,函数的参数分别是ptrFunc类型的函数指针,以及两个int型的参数。通过这个函数指针,我们就可以将同一函数签名的4个回调函数交给注册函数使用,而后面两个int型参数,刚好给回调函数使用。

所以在main函数中有:

 注册函数调用4种回调函数,输出结果如下:

是我们想要的结果。

但是这个例子,没有体现出注册回调函数的神奇之处。

 三、c语言通过回调函数实现多态

 同样是刚才的例子,我们要想完成这个输出的功能,直接在main函数中调用这4个计算函数不就好了吗?类似:

1 add(a, b);
2  
3 sub(a, b);
4 ...t);

这样代码还少,还好理解,用注册函数register来调用那4个回调函数(add, sub, mul, div)似乎显得多次一举。

为了实现多态,我们可以把register的参数封装进结构体。修改如下:

首先在函数指针下创建一个结构体,结构体中的数据包括两个int和一个函数指针。这个函数指针,我们把它叫做函数管理器。

注册函数我们现在传入的不再是3个参数,而是打包了这三个参数的结构体:

 当我们在主函数中调用的时候:

  可以发现,虽然Register函数参数没变过,都是my_data:

Register(my_data); 

但是通过改变函数管理器中的值,就可以改变 Register(my_data) 的输出。

这就实现了c语言的多态。

面向对象的多态的实现原理是一样的。

posted on   一杯清酒邀明月  阅读(2259)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
历史上的今天:
2021-08-10 MFC fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC sha
2021-08-10 resource.h
2021-08-10 VisualStudio error MSB6006: “rc.exe”已退出,代码为 5
2020-08-10 Qt 关于图片打开,另存为,保存到指定位置操作
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示