返回介绍

创建函数指针数组

发布于 2024-10-10 23:21:30 字数 2770 浏览 0 评论 0 收藏 0

这个技巧就是创建一个与回复类型一一对应的函数指针数组。在此之前,我们先看看怎么创建函数指针数组。如果想在数组中保存一组函数名,可以这样写:

replies[] = {dump, second_chance, marriage};

但这样的语法在 C 语言中行不通,如果想在数组中保存函数,就必须告诉编译器函数的具体特征:函数返回什么类型以及接收什么参数。也就是说必须使用下面这种复杂得多的语法:

如何用数组解决刚才的问题?

观察数组,函数名的顺序与枚举类型的顺序完全相同:enum response_type {DUMP, SECOND_CHANCE, MARRIAGE};

这点很重要,因为当 C 语言在创建枚举时会给每个符号分配一个从 0 开始的数字,所以 DUMP == 0, SECOND_CHANCE == 1 , 而 MARRIAGE == 2 ,也就是说可以通过 response_type 获取数 组中的函数指针。

能否用函数数组来修改之前的 main() 函数呢?

磨笔上阵

虽然这道题很难,但只要多花点时间应该没什么问题。补全这段代码所需的知识你都已经掌握了。在新版 main() 函数中,switch/case 语句已移除,你需要用一行代码来替代它,这行代码将从 replies 数组中找到对应的函数名,然后用它来调用函数。

 

磨笔上阵解答

这道题很难,新版 main() 函数中,switch/case 语句已移除,你需要用一行代码来替代它,这行代码将从 replies 数组中找到相应函数名,然后用它来调用函数。我们来分解这个表达式。

试驾

当运行新版程序时,得到了和刚才一样的输出:

区别呢?现在你用下面这行代码代替了整个 switch 语句:(replies[r[i].type])(r[i]);

如果需要在程序中多次调用回复函数,你不必复制很多代码,而当决定添加新的回复类型和函数时,只需要把它加到数组中即可:

函数指针数组让代码易于管理,它们让代码变得更短、更易于扩展,从而可以伸缩。一开始理解起来有些费劲,但函数指针数组的确可以提高 C 编程技巧。

要点

函数指针中保存了函数的地址。
函数名其实是函数指针。

11 并不完全等于,函数名是 L-value,在存储器中不分配变量。——译者注

如果你有函数

shoot() ,那么 shoot 和&shoot 都指向了 shoot() 函数。

可以用“返回类型(*变量名)(参数类型)”来声明新的函数指针。

如果 fp 是函数指针,那么可以用 fp (参数,……) 调用函数。

也可以用(*fp )(参数,……),两种情况都能工作。

C 标准库中有一个叫 qsort() 的排序函数。

qsort() 接收指向比较器函数的指针,比较器函数可以比较两个值的大小。

比较器函数接收两个指针,分别指向待排序数组中的两项。

如果把数据保存在数组中,就可以用函数指针数组将函数与数据项关联起来。

 这里没有蠢问题问:为什么函数指针的语法这么复杂?答:因为当声明函数指针时,需要说明返回类型和参数类型,这就解释了为什么有那么多的括号。问:刚才那段代码看起来有点像其他语言中面向对象的代码,是吗?答:的确很像,面向对象语言将一组函数(称为方法)与数据关联在一起。同样你也可以用函数指针将函数与数据关联在一起。问:也就是说 C 语言也是面向对象的?太好了。答:C 语言不是面向对象语言,不过一些以 C 语言为基础的语言,例如 Objective-C 和 C++,在底层使用函数指针时创建了很多面向对象的特性。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文