学C的第二十六天【指针的进阶(二)】

news2024/11/25 9:45:22

=========================================================================

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

学C的第二十五天【指针的进阶(一)】_高高的胖子的博客-CSDN博客

 =========================================================================

                     

6 . 函数指针数组

(1). 含义:

函数指针数组 一个数组,是用于存放 函数指针数组

         

例如:

                

(2). 实例 -- 计算器(转移表的使用):

计算器加法减法乘法除法 各自定义为一个函数

因为返回int类型数据参数都是 两个整数

所以可以使用 函数指针数组 存储并调用这四个函数

           

(2.1). 未使用函数指针数组的效果:

自定义函数部分:

            

主函数部分:

               

对应代码:

//计算器:
#include <stdio.h>

//加法:
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;
}

//菜单:
void menu()
{
	printf("***************************\n");
	printf("*****  1.add   2.sub  *****\n");
	printf("*****  3.mul   4.div  *****\n");
	printf("*******   0.exit   ********\n");
	printf("***************************\n");
}

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("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			//调用加法函数:
			ret = Add(x, y);
			printf("计算结果为:%d\n", ret);
			break;
		case 2:
			//输入减法函数的两个参数:
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			//调用减法函数:
			ret = Sub(x, y);
			printf("计算结果为:%d\n", ret);
			break;
		case 3:
			//输入乘法函数的两个参数:
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			//调用乘法函数:
			ret = Mul(x, y);
			printf("计算结果为:%d\n", ret);
			break;
		case 4:
			//输入除法函数的两个参数:
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			//调用除法函数:
			ret = Div(x, y);
			printf("计算结果为:%d\n", ret);
			break;
		case 0:
			printf("退出计算器\n");
			break;
		default:
			printf("选择错误,重新选择\n");
			break;
		}

	} while (input);//如果input为0则退出停止循环

	return 0;
}

                 

(2.2). 使用函数指针数组的效果 -- 转移表

             

转移表:通过函数指针数组的下标找到函数地址调用函数实现“跳转”的效果

              

自定义函数部分:

              

主函数部分:

减少代码冗余,之后添加算法只需要将添加添加函数加入 函数指针数组 再调整些参数即可

                   

对应代码:

//计算器:
#include <stdio.h>

//加法:
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;
}

//菜单:
void menu()
{
	printf("***************************\n");
	printf("*****  1.add   2.sub  *****\n");
	printf("*****  3.mul   4.div  *****\n");
	printf("*******   0.exit   ********\n");
	printf("***************************\n");
}

int main()
{
	int input = 0; //菜单选择的数
	int x = 0; //计算的第一个数
	int y = 0; //计算的第二个数
	int ret = 0; //接收函数返回值
	
	//使用函数指针数组:
	int (*pfArr[5])(int, int) = {NULL, Add, Sub, Mul, Div};
	//“挤一位” 下标:				 0	   1	2    3    4

	do
	{
		menu();
		//从键盘输入:
		printf("请选择:>");
		scanf("%d", &input);

		if (input >= 1 && input <= 4)
			//输入有效,调用函数进行计算
		{
			//输入函数的两个参数:
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			//通过 函数指针数组 来调用函数:
			ret = pfArr[input](x, y);
			// pfArr[数组下标](函数参数1,函数参数2)

			//打印计算结果:
			printf("计算结果为:%d\n", ret);
		}
		else if(input == 0) //退出
		{
			printf("退出计算器\n");
		}
		else //输入错误
		{
			printf("选择错误,重新选择\n");
		}

	} while (input);//如果input为0则退出停止循环

	return 0;
}

               

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                

7 . 指向函数指针数组的指针(了解)

(1). 含义:

本质上还是一个数组指针,只不过这里的数组函数指针数组

                 

例如:

int (*pf) (int, int);  --  函数指针

int (*pfArr [4]) (int, int);  --  函数指针数组

int (* (*p) [4]) (int, int) = &pfArr;  --  函数指针数组的指针

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

8 . 回调函数

(1). 含义:

            

回调函数就是一个通过函数指针调用的函数

           

如果你把函数的指针(地址)作为参数传递给另一个函数

当这个指针被用来调用其所指向的函数时,我们就说这是回调函数

               

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时另外的一方调用,用于对该事件或条件进行响应

                

                

(2). 实例 -- 计算器(回调函数的使用):

编写计算器函数Calc()包含之前写的加减乘除四个函数

假如Calc() 函数通过函数指针调用了加法函数,这时加法函数就是 回调函数 了。

                    

使用回调函数的效果:

自定义函数部分:

            

主函数部分:

            

对应代码:

//计算器:
#include <stdio.h>

//加法:
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;
}

//菜单:
void menu()
{
	printf("***************************\n");
	printf("*****  1.add   2.sub  *****\n");
	printf("*****  3.mul   4.div  *****\n");
	printf("*******   0.exit   ********\n");
	printf("***************************\n");
}

void Calc(int (*pf)(int x, int y)) //使用函数指针作为形参
{
	//在该函数中调用相应函数继续计算
	int x = 0;
	int y = 0;
	int ret = 0;
	printf("请输入两个操作数:");
	scanf("%d %d", &x, &y);

	//通过形参的函数指针来调用函数 -- Calc()函数就是回调函数
	ret = pf(x, y);

	printf("ret = %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");
			break;
		}

	} while (input);//如果input为0则退出停止循环

	return 0;
}

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

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

相关文章

CSDN 周赛 63 期

CSDN 周赛 63 期 参赛体验63期周赛题目题目名称:小玉家的电费题目名称:收件邮箱题目名称:饿龙咆哮-逃离城堡题目名称:寻找宝藏山小结参赛体验 这次是最近难得的四个编程题的比赛了,可惜出了一个骗分题。 然后,今天早上进入考试,还好几次,连进都进不去 嗯,最后是开着…

开源代码分享(7)—考虑电动汽车可调度潜力的充电站两阶段市场投标策略(附matlab代码)

[1]詹祥澎,杨军,韩思宁等.考虑电动汽车可调度潜力的充电站两阶段市场投标策略[J].电力系统自动化,2021,45(10):86-96. 摘要&#xff1a;在电力市场环境下,充电站优化投标策略能降低电力成本&#xff0c;甚至通过售电获取收益。文中考 虑了电动汽车成为柔性储荷资源的潜力&#…

android 下载源码 一路踩坑

python 从 2.0 升级到3.0 从官网下载 pyhon3.0 安装器,然后更改配置 # Setting PATH for Python 3.8# The original version is saved in .bash_profile.pysaveexport PATH"/Library/Frameworks/Python.framework/Versions/3.11/bin:$PATH"alias python"/Libr…

h5真机调试之ios和Android和vconsole

目录 1&#xff1a;h5真机调试之Android01&#xff1a;安卓端 小米11开启开发者模式02&#xff1a;Android edge 2&#xff1a;h5真机调试之ios1&#xff1a;iOS Safari 3&#xff1a;真机链接本地项目 之 Android &#xff08; 重点 &#xff09;3-1 vconsole的安装与使用 (…

计算机服务器中了360后缀勒索病毒怎么办,勒索病毒解密数据恢复

计算机服务器被360后缀勒索病毒攻击&#xff0c;会给企业的正常生产运转带来极大麻烦&#xff0c;最近&#xff0c;我们收到很多企业的求助&#xff0c;企业的服务器被360后缀勒索病毒攻击。360后缀勒索病毒是BeijingCrypt勒索家族的一种病毒&#xff0c;该病毒通过远程桌面攻击…

57、mysql执行计划怎么看

mysql执行计划怎么看 执行计划就是sql的执行查询的顺序&#xff0c;以及如何使用索引查询&#xff0c;返回的结果集的行数 EXPLAIN SELECT * from A where X? and Y?1、id: 是一个有顺序的编号&#xff0c;是查询的顺序号&#xff0c;有几个 select 就显示几行。id的顺序是…

[java安全]CommonsCollections1(LazyMap)

文章目录 【java安全】CommonsCollections1(LazyMap)前言LazyMap如何创建LazyMap对象&#xff1f;如何调用LazyMap的get()方法&#xff1f;如何触发AnnotationInvocationHandler#invoke()方法&#xff1f;POC总结参考 【java安全】CommonsCollections1(LazyMap) 前言 前面我们…

索尼ILCE-7SM3覆盖部分恢复案例

ILCE-7SM3&#xff0c;算是索尼的经典之作&#xff0c;目前市场占用率相当高。下边这个案例就是格式化后又拍摄了不少素材导致覆盖产生的典型情况。 故障存储:120G SD卡 故障现象: 拍摄素材后备份数据&#xff0c;设备交付其他人使用&#xff0c;结果发现少备份一条比较大的…

【grasshopper】【犀流堂】【算法】Anemone雨水径流模拟-笔记

文章目录 Anemone雨水路径模拟available options可用选项grasshopper面切线几何原理 案例1&#xff1a;surface地形1. 拾取地形曲面surface2. 曲面上根据divide surface划分点points3.将曲面上的划分点用surface closest point投影到曲面上4.align plane旋转平面x轴与世界Z夹角…

git 工具使用--分支管理

git 工具使用–分支管理 文章目录 git 工具使用--分支管理理解分支创建分支切换分支合并分支删除分支合并冲突分支管理策略分支策略bug分支删除临时分支总结 理解分支 分支管理是Git的杀手级功能之一。分支&#xff1a;就是科幻中的平行宇宙&#xff0c;当你正在电脑面前学习C…

7.15-7.16枚举题目精讲

枚举 A - TogetherB - Fractions Again? A - Together 题目描述 题意分析 题意&#xff1a;给出n个数&#xff0c;可以对每一个数做三种操作a&#xff0c;a1,a-1&#xff0c;求所有操作完成后出现次数最多的数的个数。 分析&#xff1a;对于每个数枚举三种操作后的值&#xf…

神经网络初识-以MINST数据集和CIFAR10数据集为例

文章目录 1 什么是神经网络1.1 神经元模型1.2 感知机1.3 多层神经网络1.4 为什么要使用神经网络 2 全连接神经网络2.1 简介2.2 梯度下降2.2 反向传播2.3 代码实现 3 卷积神经网络3.1 简介3.2 代码实现 总结 1 什么是神经网络 人工神经网络&#xff08;artificial neural netwo…

【论文精读】Vis-MVSNet: Visibility-aware Multi-view Stereo Network

今天属于是重读经典了&#xff0c;这是一篇发表在BMVC2020上的文章&#xff0c;试图解决MVS中可见性的问题。该文章最近在拓展之后被发表在了IJCV上。本文的解读是基于扩展之后的IJCV版本&#xff0c;期刊的版本内容更加详细一点。 文章链接&#xff1a;BMVC2020版本和IJCV版本…

【电子学会】2023年05月图形化四级 -- 绘制同心圆

绘制同心圆 1. 准备工作 &#xff08;1&#xff09;保留小猫角色&#xff1b; &#xff08;2&#xff09;背景为默认白色。 2. 功能实现 &#xff08;1&#xff09;点击绿旗&#xff0c;小猫询问“请问绘制几个同心圆&#xff1f;”&#xff1b; &#xff08;2&#xff09;…

044、TiDB特性_PlacementPolicy

Placement Rules in SQL之前 跨地域部署的集群&#xff0c;无法本地访问无法根据业务隔离资源难以按照业务登记配置资源和副本数 Placement Rules in SQL之后 跨地域部署的集群&#xff0c;支持本地访问根据业务隔离资源按照业务等级配置资源和副本数 配置 labels 设置 Ti…

这个怎么弄?电脑没有d3dx9_43.dll?

在使用某些电脑软件或游戏时&#xff0c;遇到这样的提示&#xff1a;找不到d3dx9_43.dll&#xff0c;无法继续执行代码。这个问题比较常见&#xff0c;很多人不知道该怎么解决。如果你也遇到这个问题&#xff0c;不要着急。本文将详细介绍如何解决找不到d3dx9_43.dll无法继续执…

计算机网络基础第四章

一、网络层概述 1.1 网络层功能概述 主要任务是把分组从源端传到目的端&#xff0c;为分组交换网上的不同主机提供通信服务。网络层传输单位是数据报。 功能一&#xff1a;路由选择与分组转发&#xff08;最佳路径&#xff09;功能二&#xff1a;异构网络互联功能三&#xf…

23年测试岗面试,高频自动化测试面试题(付答案)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 面试题1&#xff…

高等数学专题(1)三角函数公式大全

本帖的公式内容可以并列全网最全&#xff08;doge&#xff09;&#xff0c;博主多方面搜集并总结了最重要和常用的三角函数公式&#xff0c;具体为以下几个内容&#xff1a; 1.诱导公式 2.平方关系 3.二倍角公式 4.半角公式 5.和差角公式 6.积化和差 7.和差化积 8.辅助角公式 9…

半小时漫画计算机

ISBN: 978-7-121-41557-9 作者&#xff1a;刘欣&#xff08;码农翻身&#xff09; 绘画&#xff1a;刘奕君 页数&#xff1a;210页 阅读时间&#xff1a;2023-06-03 推荐指数&#xff1a;★★★★★ 以漫画的形式来讲解计算机的基础知识&#xff0c; 主要涉及到CPU、内存、网络…