c语言进阶部分详解(指针进阶2)

大家好!我快马加鞭接着写出指针部分part2部分。第一部分见:c语言进阶部分详解(指针进阶1)_总之就是非常唔姆的博客-CSDN博客

指针初阶部分见:c语言进阶部分详解(指针初阶)_总之就是非常唔姆的博客-CSDN博客 


一.函数指针 

1.讲解与实例 

函数指针: 在C语言中,函数指针是指向函数的指针变量。它可以像其他变量一样存储在内存中,并且可以通过函数指针来调用相应的函数。

声明函数指针:returnType (*pointerName)(parameterTypes);

其中:

  • returnType 是函数的返回类型。
  • pointerName 是函数指针的名称。
  • parameterTypes 是函数的参数类型
// 定义一个函数
int add(int a, int b) {return a + b;
}int main()
{// 声明一个函数指针int (*funcPtr)(int, int);// 将函数指针指向add函数funcPtr = add;// 通过函数指针调用函数int result = funcPtr(2, 3);  // 结果为5   平时调用函数时都是函数名(地址),也可以想通int result = (*funcPtr)(2, 3);  // 这两种均可以,funcPtr是地址,通过*解引用来找到return 0;
}

 2.《C陷阱和缺陷》中两段经典代码

2.1 ( * ( void  ( * )( ) ) 0 ) ( );

//代码1     ( * ( void  ( * )( ) ) 0 ) ( );

  1. void  ( * )( )这是一个函数指针的类型声明。它表示一个没有参数并且返回类型为void的函数指针
  2. ( void  ( * )( ) )0 这是对0进行强制类型转化,转换为函数指针类型
  3. * ( void  ( * )( ) ) 0 对地址为0的函数地址解引用
  4.  ( * ( void  ( * )( ) ) 0 ) ( ) 调用这个函数

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

//代码2 void ( * signal( int , void( * ) ( int ) ) ) (int); 

 

void (*signal(int, void (*)(int)))(int):这是一个函数声明的语法。它表示signal是一个函数,接受两个参数:一个int类型的参数和一个指向接受int类型参数并返回void的函数指针的参数。该函数返回一个指向接受int类型参数并返回void的函数指针的结果


二.函数指针数组

1.讲解与实例

函数指针数组: 函数指针数组是一个数组,其中的每个元素都是一个函数指针。可以将不同的函数指针存储在数组中,并根据需要使用它们 

 

声明函数指针数组:return_type (*array_name[size])(parameter_list); 

  1. return_type:函数指针指向的函数的返回类型。
  2. (*array_name):函数指针数组的名称。它是一个指针,指向一个数组。
  3. [size]:函数指针数组的大小。它表示数组中函数指针的数量。
  4. (parameter_list):函数指针指向的函数的参数列表

 相比于函数指针只是多了一个[ ]在函数名后面而已

// 定义函数1
void func1(int num) {printf("This is function 1. Number: %d\n", num);
}// 定义函数2
void func2(int num) {printf("This is function 2. Number: %d\n", num);
}// 定义函数3
void func3(int num) {printf("This is function 3. Number: %d\n", num);
}int main() {// 将函数指针赋值给函数指针数组的元素void(*pf[3])(int) = { &func1,&func2, &func3 };// 调用函数指针数组中的函数for (int i = 0; i < 3; i++) {pf[i](i);}return 0;
}

 

2.使用来实现计算器

 

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 = 1;int result = 0;int a = 0;int b = 0;while (input){menu();printf("请输入:\n");scanf("%d", &input);//根据menu来输入数字啦int(*pf[5])(int, int) = { NULL,add,sub,mul,div };//第一个是NUll是为了使数字与菜单对应if (input >= 1 && input <= 4){printf("请输入两个数\n");scanf("%d %d", &a, &b);result = pf[input](a, b);printf("%d\n", result);}else if(input==0){printf("退出计算器");}else{printf("输入有误,请重新输入");}}return 0;
}

三.指向函数指针数组的指针
 

指向函数指针数组的指针是一个 指针,指针指向一个数组 ,数组的元素都是函数指针
 

指向函数指针数组的指针的语法如下:

return_type (*(*pointer_name)[size])(parameter_list);

  1. return_type:函数指针指向的函数的返回类型。
  2. (*pointer_name):指向函数指针数组的指针的名称。它是一个指针,指向一个函数指针数组。
  3. [size]:函数指针数组的大小。它表示数组中函数指针的数量。
  4. (parameter_list):函数指针指向的函数的参数列表

相比与函数指针数组只是在名字前多一个*来说明是指针而已


四.回调函数

1.讲解 

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应

 2.事例

int add(int x, int y)
{return x + y;
}// 定义一个回调函数
void callback(int result) 
{printf("回调函数被调用,结果为:%d\n", result);
}// 定义一个函数,接受一个函数指针作为参数
void performOperation(int (*operation)(int, int), int a, int b, void (*callback)(int)) 
{int result = operation(a, b);callback(result);
}int main()
{// 调用函数,并传递回调函数作为参数performOperation(add, 2, 3, callback);return 0;
}

 今天的内容先到这里了,下一次不出意外是针对回调函数进行更加详细事例演示及模拟。

感谢大家的支持!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/84248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSP-J 2023 入门级 第一轮 阅读程序(2)

【题目】 CSP-J 2023 入门级 第一轮 阅读程序&#xff08;2&#xff09; #include <iostream> #include <vector> #include <algorithm> using namespace std; int f(string x, string y) {int m x.size();int n y.size();vector<vector<int>&g…

【计算机网络】深入理解TCP协议二(连接管理机制、WAIT_TIME、滑动窗口、流量控制、拥塞控制)

TCP协议 1.连接管理机制2.再谈WAIT_TIME状态2.1理解WAIT_TIME状态2.2解决TIME_WAIT状态引起的bind失败的方法2.3监听套接字listen第二个参数介绍 3.滑动窗口3.1介绍3.2丢包情况分析 4.流量控制5.拥塞控制5.1介绍5.2慢启动 6.捎带应答、延时应答 1.连接管理机制 正常情况下&…

Vulnhub系列靶机-Hackadmeic.RTB1

文章目录 Vulnhub系列靶机-Hackadmeic.RTB11. 信息收集1.1 主机扫描1.2 端口扫描1.3 目录爆破 2. 漏洞探测3. 漏洞利用3.1 反弹Shell 4. 内核提权 Vulnhub系列靶机-Hackadmeic.RTB1 1. 信息收集 1.1 主机扫描 arp-scan -l1.2 端口扫描 nmap -A -p- 192.168.188.184扫描到了…

传统的经典问题 Java 的 Interface 是干什么的

传统的经典问题 Java 的 Interface 是干什么 解答 上面的这个问题应该还是比较好回答的吧。 只要你做过 Java &#xff0c;通常 Interface 的问题多多少少会遇到&#xff0c;而且可能会遇到一大堆。 在JAVA编程语言中是一个抽象类型&#xff08;Abstract Type&#xff09;&…

SkyWalking快速上手(一)——安装单机版SkyWalking、使用SkyWalking

文章目录 什么是SkyWalking为什么选择SkyWalking安装步骤前置条件环境要求下载 SkyWalking 配置 SkyWalkingSkywalking 使用Agent 配置Collector 配置 启动 SkyWalking配置SkyWalking代理 SkyWalking的监控功能分布式调用链追踪性能指标监控告警和报警 总结 什么是SkyWalking …

javabean项目专项练习(1) 文字格斗游戏

main中是这样写的 如下是character类的描述 总结一下(个人) : 这是一题面向对象的编程, 个人编程后感是: 核心就是在于自己会不会取定义一个类, 如果是多个对象(同一个类),能不能捋顺类的方法的关系,个人觉得黑马程序员up主给出来的分析方法特别好用. 步骤: 先把在类里该该…

2. PCIE TLP解包封包

第二十一讲、PCIE的TLP包的封包解包原理.pdf 00 Packet Coding.docx 掌握如何发送接收 Mrd&#xff08;memory read TLP&#xff09;、Mwr(Memory write TLP)、Cpl(Completion TLP)和Cpld(Completion with data TLP) 命令包 1、 TLP 包是由 PCIE 的 Endpoint 或者 Root Complex…

两数之和-(哈希)

牛客网: BM50 题目: 数组中两数之和为给定值&#xff0c;返回下标 思路: 遍历数组获取idx与value&#xff0c;value为key, idx为val存入map中&#xff0c;每次遍历时判断target-value是否已在map中有值&#xff0c;值即为先前存入的下标&#xff0c;取出与当前坐标组合为数组…

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出

多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出 目录 多输入多输出 | MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向量机多输入多输出预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 MATLAB实现PSO-LSSVM粒子群优化最小二乘支持向…

60从零开始学Java之与数字相关的类有哪些?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 我们在解决实际问题时&#xff0c;会经常对数字、日期和系统设置进行处理&#xff0c;比如在我们的代…

二分搜索算法

二分搜索算法 二分搜索 对于一组有顺序的数据&#xff0c;不采用常见的遍历方式找到需要的数据&#xff0c;而是利用其规律&#xff0c;比中间数据小的一定在中间数据左边&#xff0c;比中间数据大的一定在中间数据右边&#xff0c;每次排除一般的数据&#xff0c;从而提高搜…

【算法基础】数学知识

质数 质数的判定 866. 试除法判定质数 - AcWing题库 时间复杂度是logN #include<bits/stdc.h> using namespace std; int n; bool isprime(int x) {if(x<2) return false;for(int i2;i<x/i;i){if(x%i0) return false;}return true; } signed main() {cin>&g…

SpringBoot+MyBatisPlus+MySQL不能储存(保存)emoji表情问题解决

1.之前在学习过程中不知道utf8和utf8mb4的区别&#xff0c;也没过多去了解&#xff0c;直到最近设置的数据库编码全是utf8后发现问题所在了&#xff0c;居然不能储存表情包&#xff01;&#xff01;&#xff01;整个人直接傻了&#xff0c;后面知道了utf8是3字节不能储存表情&a…

【MTK】【WFD】手机投屏到投影仪不显示画面

问题分析: 在投屏过程中,有时候会出现WFD sink端回复的video 格式表不正确,sink表示是支持VESA(3fffffff),但是当手机根据协商结果得到最优分辨率并发送给sink端时,sink端看上去没有正常播放,其实实际上应该是不支持的。 比如我们这个问题就是CES表中的0001ffff,最大…

SadTalker 让图片说话

参考&#xff1a;https://github.com/OpenTalker/SadTalker 其他类似参考&#xff1a;https://www.d-id.com/ 输入图片加音频产生2d视频 安装使用 1、拉取github&#xff0c;下载对应安装库 2、下载对应模型baidu网盘 新建checkpoints&#xff0c;把下载sadtalker里模型拷贝进…

层次查询和分析函数(LAG、LEAD)在号段选取中的应用

1. 问题的提出 在实际工作中&#xff0c;我们常常会碰到号段选取的问题&#xff0c;例如&#xff1a; 一组连续的数&#xff0c;去掉中间一些数&#xff0c;要求出剩下的数的区间&#xff08;即号段&#xff09;例如&#xff1a;一串数字为1,2,3,4,7,9,10&#xff0c;则号段为…

如何在Gazebo中实现多机器人编队仿真

文章目录 前言一、仿真前的配置二、实现步骤1.检查PC和台式机是否通讯成功2.编队中对单个机器人进行独立的控制3、对机器人进行编队控制 前言 实现在gazebo仿真环境中添加多个机器人后&#xff0c;接下来进行编队控制&#xff0c;对具体的实现过程进行记录。 一、仿真前的配置…

JAVAEE初阶相关内容第十二弹--多线程(进阶)

目录 一、JUC的常见类 1、Callable接口 1.1callable与runnable 1.2代码实例 &#xff08;1&#xff09;不使用Callable实现 &#xff08;2&#xff09;使用Callable实现 1.3理解Callable 1.4理解FutureTask 2、ReentrantLock 2.1ReentrantLock的用法 2.2ReentrantLoc…

【面试题】Js数组去重都有哪些方法?

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 表妹一键制作自己的五星红旗国庆头像&#xff0c;超好看 1. indexOf 定义&#xff1a; indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置…

springboot整合sentinel完成限流

1、直入正题&#xff0c;下载sentinel的jar包 1.1 直接到Sentinel官网里的releases下即可下载最新版本&#xff0c;Sentinel官方下载地址&#xff0c;直接下载jar包即可。不过慢&#xff0c;可能下载不下来 1.2 可以去gitee去下载jar包 1.3 下载完成后&#xff0c;进行打包…