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

拿捏c语言指针(下)

前言

此篇讲解的主要是函数与指针的那些事~

书接上回  拿捏c语言指针(上)和  拿捏c语言指针(中)

​​​​​​没有看的小伙伴要抓紧喽~

 欢迎关注​​个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



函数指针变量

函数指针变量 用于存放函数的地址

其中,函数名==函数地址,&Add可以换成Add

*pf==&Add ,也就是说Add、*pf、pf三者都可以调用函数

两段有趣的代码

(*(void(*)())0)()

拆分(*( void(*)() 0)() 

void(*)() 函数指针类型,此函数没有参数,返回值是void

void(*)() )0 是将0这个整数值强制类型转换为一个函数的地址。

*( void(*)() 0 是解引用,

(*( void(*)() 0)() 是调用地址为0处的函数

void(* signal ( int,void(*)(int) ) )(int);

拆分void(* signal ( int,void(*)(int) ) )(int);

signal是一个函数,其参数有2个,int类型和函数指针类型void(*)(int) ,该指针指向的函数参数是int,返回值是void。

signal函数的返回类型是void(*  )(int)函数指针 类型,该指针指向的函数参数是int,返回值是void。

typedef类型重命名

  • 可以将复杂的类型名字重命名

如:typedef unsigned int uint;

  • 对于指针类型重命名

如:typedef int* ptr_t;

  • 对于数组指针函数指针类型重命名  与以上有区别,新的名字要放在里面

如:typedef int(*parr_t)[5];   parr_t是数组指针类型新的名字
如:typedef void(*pf)(int);     pf是函数指针类型新的名字

所以我们可以将void(* signal ( int,void(*)(int) ) )(int);

简化为以下两句代码

typedef  void(*ptr_t)(int)  ;  重命名void(*)(int) ptr_t

ptr_t  signal(int,ptr_t);  signal函数的参数类型是int和ptr_t,返回值类型是ptr_t


函数指针数组

函数指针数组本质上是一个数组,里面存放的是函数指针变量 

如下代码中

int(*pfArr[4])(int, int) = { Add,Sub,Mul,Div };//pfArr就是一个函数指针数组,可以存放4个元素         

//加法函数
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(*pf)(int, int) = &Add;//pf是函数指针int(*pfArr[4])(int, int) = { Add,Sub,Mul,Div };//pfArr是函数指针数组return 0;
}

函数指针数组应用--实现一个简易计算器

实现一个简易计算器,有 加减乘除 功能。

代码实现

利用函数指针数组存放计算函数地址,方便调用。

如下代码中,int(*pfArr[5])(int, int) = { NULL,Add,Sub,Mul,Div };数组下标0处设为NULL,方便其他计算函数对应菜单标号

#include<stdio.h>
//计算器菜单
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(*pfArr[5])(int, int) = { NULL,Add,Sub,Mul,Div };//pfArr是函数指针数组//                            0   1   2    3    4do{menu();printf("请选择:>");scanf("%d", &input);if (input == 0){printf("退出计算器\n");}else if (input >= 1 && input <= 4){printf("请输入两个操作数:>");scanf("%d%d", &x, &y);int ret = pfArr[input](x,y);printf("结果是:%d\n", ret);}else{printf("选择错误,请重新选择\n");}} while (input);return 0;
}

  结果展示                                    

       


回调函数

回调函数就是⼀个通过函数指针调⽤的函数。

把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。

其中qsort函数的运用是 回调函数 典例

可以参考 手撕qsort函数~ ​​​​​​​本篇就不再赘述了                                            

http://www.lryc.cn/news/302864.html

相关文章:

  • Spring源码笔记之SpringIOC--(3)什么是BeanFactory?
  • 微信小程序之会议OA个人中心后台交互
  • 代码随想录算法训练营第52天(动态规划09 ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III
  • 微服务篇之负载均衡
  • wayland(xdg_wm_base) + egl + opengles 使用FBO渲染到纹理实例(六)
  • 基于 RisingWave、Instaclustr 和 Apache Superset 对维基百科实时监控
  • 建站用帝国CMS好还是WordPress好
  • 深度学习基础之《TensorFlow框架(2)—图》
  • Web3区块链游戏:创造虚拟世界的全新体验
  • 单机启动/开机启动SpringBoot服务的正确方式
  • [C#]winform基于opencvsharp结合CSRNet算法实现低光图像增强黑暗图片变亮变清晰
  • 抓包分析 TCP 协议
  • 代码随想录算法训练营day27 | 93.复原IP地址、78.子集、90.子集II
  • RuntimeError: CUDA out of memory.【多种场景下的解决方案】
  • LeetCode刷题| Leetcode 45. 跳跃游戏,1190. 反转每对括号间的子串,781. 森林中的兔子,739. 每日温度
  • Redis(03)——发布订阅
  • ⭐北邮复试刷题LCR 034. 验证外星语词典__哈希思想 (力扣119经典题变种挑战)
  • ECMAScript 6+ 新特性 ( 二 )
  • JS游戏项目合集【附源码】
  • React中hooks使用限制及保存函数组件状态
  • 用git命令来上传项目到GitHub我自己的仓库
  • .NET有哪些微服务框架
  • uniapp中打开蓝牙需要哪些权限
  • virtualbox虚拟机运行中断,启动报错“获取 VirtualBox COM 对象失败”
  • 【JVM篇】什么是运行时数据区
  • Jetpack 之Glance+Compose实现一个小组件
  • 实时矢量搜索如何彻底改变各行各业?
  • 【Linux】指令 【scp】
  • 文件IO,目录IO的学习
  • leetcode(动态规划)53.最大子数组和(C++详细解释)DAY12