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

C语言 指针的理解 — 3

什么是函数指针?

和数组指针有些类似,指向函数的指针就是函数指针

其实函数也是有地址的:

int Add(int x, int y) { return x + y; } int main() { printf("%p\n", &Add); printf("%p\n", Add); return 0; }

这里的 &Add 和 Add 的效果是一样的,取出的都是函数的地址。

既然可以得到函数的地址那么函数也是存在的。

int(*pf)(int, int) = &Add;

左边的 int 表示函数的返回类型是 int,右边的(int ,int)是函数的参数的类型。

函数指针的书写形式是和函数返回类型以及函数的参数密切相关的

函数指针有什么用?

通过存放函数的地址,间接访问函数,和其他指针的作用是一样的。

int Add(int x, int y) { return x + y; } int main() { int(*pf)(int, int) = &Add; int ret = (*pf)(2, 3); printf("%d\n", ret); ret = pf(3, 4); printf("%d\n", ret); return 0; }

这个 * 可写可不写,效果相同。

下面是函数指针的应用场景:

void menu() { printf("**********************\n"); printf("*** 1.Add 2.Sub ****\n"); printf("*** 3.Mul 4.Div ****\n"); printf("*** 0.Exit ****\n"); printf("**********************\n"); } int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; do { menu(); printf("请输入>"); scanf("%d", &input); switch (input) { case 1: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Add(x, y); printf("%d\n", ret); break; case 2: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Sub(x, y); printf("%d\n", ret); break; case 3: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Mul(x, y); printf("%d\n", ret); break; case 4: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Div(x, y); printf("%d\n", ret); break; case 0: printf("退出\n"); break; default: printf("输入错误\n"); } } while (input); return 0; }

可以发现:进入case语句时代码是非常冗余的,如果想把调用算数的冗余代码,分装成一个函数,但又要做到实现不同的函数调用时,函数指针就会帮大忙。

把代码用函数指针写成这样,就会大大减少冗余度。这种方法其实是回调函数的使用

void calc(int pf(int , int )) { int x = 0; int y = 0; printf("请输入2个数"); scanf("%d %d", &x, &y); int ret = pf(x, y); printf("%d\n", ret); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; do { menu(); printf("请输入>"); scanf("%d", &input); switch (input) { case 1: calc(Add); break; case 2: calc(Sub); break; case 3: calc(Mul); break; case 4: calc(Div); break; case 0: printf("退出\n"); break; default: printf("输入错误\n"); } } while (input); return 0; }
http://www.jsqmd.com/news/1108071/

相关文章:

  • 虚假信息治理新范式:跨层协同人机耦合防御体系
  • Grafana 生产环境运维与排错:日志、权限与升级实战
  • Grafana 告警历史与复盘:使用 Loki 和 Tempo 追踪告警链路
  • 什么是选择自己适合的赛道?
  • 【JVS更新日志】APS排产、JVS规则引擎、JVS低代码开发套件、在线白板(插件)等7.1更新说明!
  • 实体生意抖音获客起号指南,让你持续获客
  • YimMenu:GTA5玩家的终极安全增强方案与游戏体验优化指南
  • 2026年7月最新全球小程序开发服务商推荐:选型标准 + 排行 + 深度评测,含零代码SAAS、AI编程、源码定制
  • 终极GTA5增强工具:YimMenu完全防护与游戏体验提升指南
  • 2026找搭子防骗全攻略!高效解锁纯净靠谱社交
  • 一键智能激活:KMS_VL_ALL_AIO让你的Windows和Office永久激活无忧
  • PVZ Toolkit:植物大战僵尸终极修改器的完全掌控指南
  • 3分钟搞定抖音评论采集:零代码工具让数据分析触手可及
  • VMware Tools与open-vm-tools深度对比(2024 LTS版实测数据全公开)
  • 22-杨逢昌:制造业车间6S常态化维稳方案——三级检查节拍标准化管理体系
  • DXVK终极指南:如何通过跨平台图形API转换实现Linux高性能渲染
  • 我把一坨原始素材扔进文件夹,对AI说了句话,它直接还我一条成片
  • 为什么口腔组织微环境研究需要空间单细胞蛋白组?
  • KMS_VL_ALL_AIO:Windows与Office激活的一站式解决方案
  • 盘锦车衣车膜手工裁剪,边角更要细看
  • AI编程助手部署避坑指南:从环境配置到稳定运行
  • 终极.NET逆向工具:dnSpy完整指南与7个实战技巧
  • Selenium三大等待机制详解:从time.sleep到WebDriverWait的自动化同步策略
  • HsMod:炉石传说55项进阶功能增强插件完整指南
  • NifSkope深度解析:Bethesda游戏引擎3D模型编辑核心技术实战
  • 【企业级渗透测试环境构建标准】:为什么92%的初学者VMware装Kali会触发SElinux告警?权威配置白皮书首发
  • 从裸机到渗透靶场只需18分钟:VMware Workstation Pro 17 + Kali 2024.1全链路实操,含OVA镜像直装秘钥
  • 3分钟搞定!B站视频下载神器:免费保存大会员4K和充电专属视频
  • IvorySQL 社区邀你参战|2026 直通乌镇开源竞技挑战赛:高质量贡献,让技术实力被看见
  • 创新自动化驱动解决方案:Apple-Mobile-Drivers-Installer技术深度解析