news 2026/5/2 10:37:27

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入浅出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语言开发、面试中的绝大多数函数指针问题。

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

Python 爬虫高级实战:HTTP/2 协议爬虫请求优化

前言 在传统爬虫开发体系中,绝大多数网络请求均基于 HTTP/1.1 协议完成数据交互,该协议诞生已久,技术架构成熟且适配性极强,但在高并发请求、多资源并行加载、网络传输效率层面存在天然短板。随着互联网服务架构持续升级,各大主流平台、大型电商、资讯门户、接口服务端已…

作者头像 李华
网站建设 2026/5/2 10:31:44

FigmaCN:为中文设计师量身打造的Figma界面汉化解决方案

FigmaCN&#xff1a;为中文设计师量身打造的Figma界面汉化解决方案 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 如果你是一位使用Figma进行设计工作的中文用户&#xff0c;是否曾因英…

作者头像 李华
网站建设 2026/5/2 10:28:46

HuggingClaw:自动化挖掘Hugging Face AI资源的开源工具集

1. 项目概述&#xff1a;当AI民主化遇见开源协作最近在AI开源社区里&#xff0c;一个名为“HuggingClaw”的项目引起了我的注意。这个名字本身就很有意思&#xff0c;它巧妙地将“Hugging Face”和“Claw”&#xff08;爪子&#xff0c;常用来比喻抓取、收集&#xff09;结合在…

作者头像 李华
网站建设 2026/5/2 10:28:21

基于Cloudflare Workers与OpenAI API构建智能Telegram机器人

1. 项目概述&#xff1a;一个部署在Cloudflare Workers上的智能Telegram机器人 如果你和我一样&#xff0c;既想体验ChatGPT的便利&#xff0c;又希望有一个私密、可控且成本极低的对话入口&#xff0c;那么 tbxark/ChatGPT-Telegram-Workers 这个项目绝对值得你花时间研究。…

作者头像 李华