当前位置: 首页 > news >正文

深入浅出C语言函数指针:从入门到实战(附完整代码实例)

在C语言的学习中,函数指针是一个核心且进阶的知识点,它既可以让代码更灵活、更具扩展性,也是实现回调函数、动态分发、模块化编程的关键。本文结合百度、必应的高频讲解思路,用通俗的语言+完整可运行的代码,带你彻底掌握函数指针。

一、什么是函数指针?

简单来说:函数指针是指向函数的指针变量

  • 普通指针指向变量的内存地址,函数指针指向函数的代码段内存地址
  • 函数名本身就是函数的入口地址,因此可以直接赋值给函数指针;
  • 通过函数指针,我们可以像调用函数一样调用指针,实现动态调用函数。

函数指针的标准定义格式

// 基础格式返回值类型(*指针变量名)(参数类型1,参数类型2,...);

示例:

// 定义一个函数指针pFunc,指向【返回int、参数为两个int】的函数int(*pFunc)(int,int);

二、基础实战:函数指针的定义、赋值、调用

这是最基础的用法,帮你快速理解核心逻辑。

完整代码

#include<stdio.h>// 定义两个普通函数intadd(inta,intb){returna+b;}intsub(inta,intb){returna-b;}intmain(){// 1. 定义函数指针:指向返回int、参数为两个int的函数int(*pFunc)(int,int);// 2. 赋值:函数名就是地址,直接赋值pFunc=add;// 指针指向add函数// 3. 通过指针调用函数(两种写法等价)printf("3 + 5 = %d\n",pFunc(3,5));// 推荐写法printf("3 + 5 = %d\n",(*pFunc)(3,5));// 传统写法// 4. 重新赋值,指向sub函数pFunc=sub;printf("10 - 4 = %d\n",pFunc(10,4));return0;}

运行结果

3 + 5 = 8 3 + 5 = 8 10 - 4 = 6

核心要点

  1. 函数指针必须和指向的函数签名一致(返回值、参数类型/个数完全相同);
  2. (*pFunc)的括号不能省略,否则会变成「返回指针的函数」;
  3. 调用时,pFunc()(*pFunc())效果完全一样,推荐简写。

三、进阶用法:函数指针数组(批量管理函数)

当我们需要批量调用多个同类型函数时,函数指针数组是最优解,常用于菜单选择、命令分发等场景。

适用场景

计算器功能选择、游戏指令分发、模块化功能调用。

完整代码

#include<stdio.h>// 定义四个运算函数intadd(inta,intb){returna+b;}intsub(inta,intb){returna-b;}intmul(inta,intb){returna*b;}intdiv(inta,intb){returnb!=0?a/b:0;}intmain(){// 定义函数指针数组:存储4个同类型函数的地址int(*pArr[4])(int,int)={add,sub,mul,div};intx=20,y=5;// 批量调用printf("加法:%d\n",pArr[0](x,y));printf("减法:%d\n",pArr[1](x,y));printf("乘法:%d\n",pArr[2](x,y));printf("除法:%d\n",pArr[3](x,y));return0;}

运行结果

加法:25 减法:15 乘法:100 除法:4

四、高级实战:函数指针作为函数参数(回调函数)

这是函数指针最常用、最重要的用法——回调函数:把一个函数作为参数传给另一个函数,在合适的时机被调用。

适用场景

排序函数、事件处理、异步操作、遍历数据。

完整代码:通用遍历+回调处理

#include<stdio.h>// 回调函数指针:定义参数类型// 作用:让printArray可以调用不同的打印逻辑typedefvoid(*Callback)(int);// 通用遍历函数:接收数组、长度、回调函数voidprintArray(intarr[],intlen,Callback func){for(inti=0;i<len;i++){func(arr[i]);// 调用回调函数处理每个元素}printf("\n");}// 自定义回调函数1:普通打印voidshowNum(intnum){printf("%d ",num);}// 自定义回调函数2:打印平方voidshowSquare(intnum){printf("%d ",num*num);}intmain(){intarr[]={1,2,3,4,5};intlen=sizeof(arr)/sizeof(arr[0]);printf("原数组:");printArray(arr,len,showNum);// 传入普通打印函数printf("平方值:");printArray(arr,len,showSquare);// 传入平方打印函数return0;}

运行结果

原数组:1 2 3 4 5 平方值:1 4 9 16 25

核心优势

  • 代码解耦:printArray只负责遍历,不关心具体处理逻辑;
  • 高度灵活:传入不同回调函数,实现不同功能。

五、简化代码:typedef 重定义函数指针

复杂的函数指针定义可读性差,用typedef可以简化写法,这是企业开发的标准用法。

示例

// 原始写法int(*pFunc)(int,int);// typedef 重定义(推荐)typedefint(*CalcFunc)(int,int);// 直接使用别名定义指针CalcFunc p=add;

六、函数指针的常见误区

  1. 括号不能丢
    • 正确:int (*p)(int)→ 函数指针
    • 错误:int *p(int)→ 返回int*的函数声明
  2. 函数签名必须匹配
    返回值、参数个数、参数类型有一个不同,都不能赋值。
  3. 无需手动分配/释放内存
    函数指针指向代码段地址,不需要malloc/free

总结

  1. 函数指针 = 指向函数的指针,核心用途:动态调用函数、实现回调、批量管理函数
  2. 基础用法:定义→赋值→调用;
  3. 进阶用法:函数指针数组(批量调用)、函数指针做参数(回调函数);
  4. 简化写法:用typedef重定义函数指针,提升代码可读性。

以上代码均可直接复制编译运行,覆盖了函数指针的高频考点+实战场景,吃透这些,足以应对C语言开发、面试中的绝大多数函数指针问题。

http://www.jsqmd.com/news/737500/

相关文章:

  • 100个Proteus仿真项目持续更新(免费获取+视频讲解)
  • 明日方舟MAA助手:3分钟掌握全自动刷图基建管理终极指南
  • UnrealPakViewer架构深度解析:Pak文件解析的核心技术实现
  • 告别本地显卡焦虑:用阿里云PAI-DSW部署ChatGLM3,实测3060笔记本与云端V100性能对比
  • 开源MiniClaw机械爪:8421编码器理念下的嵌入式抓取方案
  • Llama3.1的工具调用和Llama4的MoE架构实战:新特性如何改变你的开发流程?
  • RH850 F1 ADC配置避坑指南:从采样时间到虚拟通道,手把手调通你的第一个AD转换
  • 技术革命:八大网盘直链解析的智能解决方案
  • 毕业季不焦虑:用百考通AI搞定论文查重与AIGC检测,高效通关秘籍
  • 终极指南:AntiMicroX游戏手柄映射工具的技术架构与实战配置
  • 在公共服务器上构建 RK3588 SDK 的纯净 Docker 方案
  • AUTOSAR SecOC实战:FVM模块的四种新鲜度验证模式,到底该怎么选?
  • 具身智能论文问答(三):Open VLA
  • 保姆级教程:用Rufus制作Win10安装U盘,从下载镜像到BIOS设置一步不落
  • AGI Agent:开源自主智能体平台部署与实战指南
  • 如何突破Mac硬件限制:OpenCore Legacy Patcher终极升级方案
  • 2026年武汉拍摄宣传片流程大揭秘!实战榜单带你一探究竟 - 品牌推荐官方
  • 使用mcpkit快速构建AI代理工具:MCP协议Python开发指南
  • 终极罗技鼠标宏配置指南:3步实现绝地求生零后坐力压枪
  • 基于ESP32-S3与AMOLED屏的嵌入式AI助手可视化交互系统开发实践
  • XHS-Downloader:小红书无水印作品下载与内容管理解决方案
  • 别再傻傻分不清了!一张图看懂QA、QE、QC在软件测试团队里的真实分工
  • 星穹铁道自动化终极指南:三月七小助手如何5分钟解放你的游戏时间
  • ESP32串口通信保姆级教程:从Serial.begin()到多设备数据交换(附避坑指南)
  • 2026年成都AI搜索优化推广公司TOP7权威排行榜,为你揭晓哪家强! - 品牌推荐官方
  • 毕业季不再焦虑:百考通AI一站式解决论文查重与AIGC难题
  • Forge.OpenAI.ErrorOr:优雅处理OpenAI API错误的函数式解决方案
  • 2026年广州宣传片制作费用揭秘!实战榜单带你了解行情 - 品牌推荐官方
  • 智慧农业水稻稻曲病检测数据集VOC+YOLO格式357张3类别
  • ESP32开发环境二选一?深度对比VSCode的Espressif IDF插件与PlatformIO插件