news 2026/5/1 22:00:55

C语言指针(七)最终篇——指向函数指针数组的指针

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言指针(七)最终篇——指向函数指针数组的指针

上节回顾:

C语言指针(六)——函数指针数组

上一节我们学习了函数指针数组,它让菜单驱动的代码变得简洁优雅。通过将多个函数指针存储在一个数组中,我们彻底摆脱了繁琐的switch语句,实现了代码的高扩展性。

今天,我们要在这个基础上更进一步,学习指针的"终极套娃"——指向函数指针数组的指针。别被名字吓到,其实理解了本质,你会发现它很简单。

指向函数指针数组的指针

一、为什么需要这个"套娃指针"?

先思考一个问题:既然函数指针数组这么好用,为什么还要学指向它的指针?

答案很实在:实际开发中确实很少直接使用。但学习它有重要价值:

  1. 理解C语言类型系统的完整性

  2. 能看懂任何复杂的C语言声明

  3. 面试时展示扎实的指针功底

  4. 为理解更复杂的系统代码打下基础

就像学习数学公式,你可能不会天天用,但懂了之后,看世界的方式会不同。

二、什么是"指向函数指针数组的指针"?

让我们用最直白的方式解释:

  1. 函数指针:指向单个函数的指针

  2. 函数指针数组:存放多个函数指针的数组

  3. 指向函数指针数组的指针:指向这个数组的指针

简单说:这是一个指针,它指向一个数组,而这个数组里存的全是函数指针。

三、如何定义?

不必着急,我们一步一步来~

第1步:先定义函数指针数组

// 定义一个函数指针数组,包含3个元素 int (*funcArr[3])(int, int);

第2步:取这个数组的地址

&funcArr // 这就是"指向函数指针数组的指针"类型

第3步:定义指针变量存储这个地址

int (*(*p)[3])(int, int) = &funcArr;

我们来解析一下这一长串:int (*(*p)[3])(int, int)

  • *p:p是一个指针

  • (*p)[3]:p指向一个包含3个元素的数组

  • *(*p)[3]:数组的每个元素是指针

  • (int, int):这些指针指向的函数接受两个int参数

  • 最前面的int:函数返回int类型

四、用typedef让代码变清晰

对于复杂声明,typedef是救命稻草

// 第1步:定义函数指针类型 typedef int (*FuncPtr)(int, int); // 第2步:用这个类型定义数组 FuncPtr funcArr[3]; // 第3步:定义指向这个数组的指针 FuncPtr (*p)[3] = &funcArr;

看,用了typedef,代码立刻变得简单多了!

五、简单示例

#include <stdio.h> // 两个简单的测试函数 int Add(int a, int b) { return a + b; } int Sub(int a, int b) { return a - b; } int main() { // 定义函数指针数组并初始化 int (*funcArr[2])(int, int) = {Add, Sub}; // 定义指向这个数组的指针 int (*(*p)[2])(int, int) = &funcArr; // 使用数组直接调用 printf("直接使用数组:\n"); printf("Add(10, 5) = %d\n", funcArr[0](10, 5)); printf("Sub(10, 5) = %d\n", funcArr[1](10, 5)); // 通过指针调用 printf("\n通过指针调用:\n"); printf("Add(10, 5) = %d\n", (*p)[0](10, 5)); // 先解引用p得到数组 printf("Sub(10, 5) = %d\n", (*p)[1](10, 5)); // 查看地址 printf("\n地址信息:\n"); printf("funcArr地址:%p\n", funcArr); printf("&funcArr地址:%p\n", &funcArr); printf("p存储的地址:%p\n", p); return 0; }

运行结果:

直接使用数组:
Add(10, 5) = 15
Sub(10, 5) = 5

通过指针调用:
Add(10, 5) = 15
Sub(10, 5) = 5

地址信息:
funcArr地址:0x7ffc5a3b2b20
&funcArr地址:0x7ffc5a3b2b20
p存储的地址:0x7ffc5a3b2b20

六、注意点

1.funcArr&funcArr的区别

虽然打印的地址值相同,但类型完全不同

  • funcArr:类型是int (**)(int, int)(指向函数指针的指针

  • &funcArr:类型是int (*(*)[2])(int, int)(指向数组的指针

2. 指针运算的差异

printf("funcArr + 1 = %p\n", funcArr + 1); // 前进8字节(一个指针大小) printf("&funcArr + 1 = %p\n", &funcArr + 1); // 前进16字节(整个数组大小)

这就是为什么类型很重要——决定了指针运算的步长。

3. 如何正确访问

// 正确:先解引用,再下标访问 int result1 = (*p)[0](10, 5); // 错误:试图直接下标访问 int result2 = p[0](10, 5); // 编译错误

记住要先解引用才能取元素!

七、总结

本节我们了解了什么指向是函数指针数组的指针,并了解了它的简单用法。本节内容不做重点,只需了解即可,考试和实际开发使用的并不多。

完结撒花

指针系列的探索之路,至此已抵达终点。从最基础的指针概念出发,我们一路经历了字符指针、指针数组、数组指针的层层递进,攻克了函数指针这一重要关口,直至本篇的指向函数指针数组的指针。这一路走来,宛如攀登一座知识的山峰,每一步都见证了思考的深度。

学习指针的道路绝非坦途,相信许多同学都曾经历过困惑与挣扎——那些面对复杂声明时的迷茫,调试指针错误时的挫败,都是成长路上必经的风景。不必焦虑,更不必自我怀疑,因为每一位C语言学习者都曾走过相似的路径。回顾我的学习历程,也是通过一行行代码的实践、一篇篇笔记的积累、一次次错误的修正,才逐渐拨开迷雾,看清指针世界的真实面貌。

我相信,所有真诚的努力都不会被辜负!

愿大家在编程的道路上一往无前,用代码书写属于自己的精彩篇章!

希望讲解的内容能帮助到各位同学,如有错误或更好的建议还望指出 ~

谢谢大家!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 7:29:21

Java 1.8在企业级项目中的5个最佳实践

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个企业级员工管理系统&#xff0c;使用Java 1.8特性实现&#xff1a;1.基于Lambda的查询过滤 2.Stream处理薪资计算 3.使用新的日期API管理入职时间 4.Optional处理可能为nul…

作者头像 李华
网站建设 2026/4/30 23:56:27

软工毕设简单的选题帮助

文章目录&#x1f6a9; 1 前言1.1 选题注意事项1.1.1 难度怎么把控&#xff1f;1.1.2 题目名称怎么取&#xff1f;1.2 选题推荐1.2.1 起因1.2.2 核心- 如何避坑(重中之重)1.2.3 怎么办呢&#xff1f;&#x1f6a9;2 选题概览&#x1f6a9; 3 项目概览题目1 : 图像隐写算法研究与…

作者头像 李华
网站建设 2026/5/1 7:28:18

《2025养老护理员职业现状调研报告》深度解读:550万护理员缺口背后,破局关键在哪?

养老护理员走向年轻化、专业化、职业化作者 | AgeClub杨佳璇、陈婉儿、卫元褀前言养老照护已经成为国家、社会和家庭必须共同应对的紧迫挑战&#xff0c;“银发经济”的宏大叙事要从最具体的服务与关怀开始。庞大需求是这一切的起点。 截至2024年底&#xff0c;我国60岁及以上人…

作者头像 李华
网站建设 2026/5/1 10:02:29

真实案例:某金融系统如何选择分布式事务方案

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 模拟一个金融支付系统场景&#xff0c;包含账户服务和交易服务。要求&#xff1a;1. 生成四种分布式事务方案在该场景下的具体实现代码 2. 提供各方案在1000TPS压力下的性能测试报告…

作者头像 李华
网站建设 2026/5/1 1:19:04

EmotiVoice企业版即将发布:新增商业功能与技术支持

EmotiVoice企业版即将发布&#xff1a;新增商业功能与技术支持 在虚拟偶像直播中突然情绪转折&#xff0c;从欢快跳跃切换到深情回忆——如果语音还是平铺直叙的机械朗读&#xff0c;观众瞬间就会“出戏”。这正是当前AI语音技术面临的核心挑战&#xff1a;我们不再满足于机器“…

作者头像 李华
网站建设 2026/5/1 7:40:42

基于springboot的运动服装销售系统的设计与实现

本文针对运动服装行业数字化转型需求&#xff0c;设计并实现了基于Spring Boot的运动服装销售系统。系统采用微服务架构与前后端分离技术&#xff0c;整合智能推荐算法、实时库存监控和动态定价策略&#xff0c;有效提升用户体验与企业运营效率。研究通过需求分析明确用户、商家…

作者头像 李华