C语言-------指针进阶(2)

1.指针数组

指针数组表较简单,类比整型数组,字符数组,整型数组里面的元素都是整型变量,字符数组里面

的元素是字符类型,那么指针数组就是数组里面的每个元素都是指针类型,例如int*arr[5]就是一个

指针数组,数组里面的元素都是int*的指针类型;

2.数组指针

数组指针是什么,如何使用,我们回忆一下二维数组传参,我们知道一维数组的传参,例test函数

test(arr)参数arr是数组名,就是数组首个元素的地址,我们也可以使用数组接受,也可以使用指针

指向首个元素的地址,通过指针的移动打印数组的元素;

同理,二维数组传参,例如arr[3][5],传递参数test(arr),arr是二维数组的名字,但是不是设个元素的

地址,而是首行元素的地址,这个时候如果想要使用指针接受,这个指针就应该是数组指针,指向

的是一个数组,还是拿这个3行5列数组举例,对于二维数组我们可以这样理解,把二维数组理解成

3个一维数组,实际上传递进去的是第一行以为数组的地址,有5个元素,我们使用数组指针

int(*p)[5]进行接收,这个数组指针表示指向5个元素,每个元素的类型是int类型,数组指针的名字

是p指针,指针类型int(*)[5],指针的类型决定了对指针进行加一操作会跳过几个字节,如果是普通的

整形指针数组,加一就跳过4个字节,但是这里的p指针的类型是int(*)p,所以加一会跳过5个元素,

也就是20字节。

3.函数指针变量

我们知道数组名表示 数组首个元素的地址,函数名同样表示函数的地址,取地址数组名表示整个

数组的地址,但是取地址函数名仍然是函数的地址,和直接的函数名没有区别

图片里面int (*p)(int,int)就是定义函数指针,这个函数指针的参数有2个,都是int类型

这个函数的返回类型是int类型,实际上在进行调用的时候,加上星号只是为了表示他是函数指针

加上2个或者多个星号都不影响使用,不加星号都是可以的,通过打印结果也可以知道,

看似,即使没有函数指针,我们也可以对函数进行使用,实际上后续函数指针会发挥巨大作用

4.二段有趣的代码分析

1 (*(void (*)())0)();

这个里面的void(*)()是函数指针类型,放在括号里面就是进行强制类型转换,把0转换成函数指针类

型,0是个地址,这里的星号同上,是可以省略的,调用0地址处的这个函数,(这里面的0仅仅是一

个地址)这个函数指针没有参数,传递的参数也是空的,如果要调用100地址处的函数,就是

100,总言之,这是一次函数的调用;

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

这个里面的void(*)(int)也是函数指针变量,参数int类型,返回void类型,signal是一个函数,函

数的参数是int类型,和函数指针类型,去掉后是void(*)(int)还是一个函数指针类型,也就是这个函

数的返回值是函数指针类型,函数的声明只需要高数参数的类型,可以不写名字,可能初学者会问

可不可以写为void(*)(int)  signal(int,void(*)(int),或许这样写更加清楚,但是编译器不支持;实质上

这个是函数的声明;

5.typedef关键字的使用

上面的这个例子,对于比较长的数据类型或者指针类型,名字我们可以进行简化,这个时候就有了

typedef关键字

typedef unsigned int  ptr就是把unsigned int这个比较长的类型用ptr代替

我们定义unsigned int a=10;就可以直接写为ptr a=10,使得原来复杂代码简单化,就是重新起名字

还例如指针类型也可以进行简化,int*类型也可以这样简化,typedef int* asd,就是简化后名字asd

int(*p)[5]是数组指针,类型int(*)[5],也可以重新命名,不是int(*)[5] ptr,需要写为typedef int(*ptr)[5]

ptr也是一种类型了,平时的int(*p2)[5]=&arr(这里的p2就是指针变量)就可以写为ptr p2=&arr,

函数指针类型重命名,原来的 void (*pf)(int)函数指针,typedef  void(*)(int)  ptr;以后定义就可以

写作ptr p2=&add,这样定义函数指针类型;

同样使用ptr重命名函数指针,void (*signal(int , void(*)(int)))(int);就可以简化为

ptr signal(int,ptr),变得更加简单,简洁高效。

typrdef  int* ptr;就是关键字重命名;

#define int* PTR就是遇到PTR使用int*替代,ptr a相当于int*a,这样也可以简化;

第一一个变量的时候两者无区别,定义2个时候就有区别

ptr  a,b;可以同时定义a,b都是int*类型

PTR a,b;不能同时定义a,b是int*类型,只能定义a ,b还是默认的int 类型;

由此可见,使用重命名的时候,尽量使用typedef,使用#define可能会出现问题。

6,函数指针数组

(1)首先讲一下函数指针数组如何使用:

每一个运算的法则都是函数指针,因为他们的参数,返回类型都是相同的,所以我们可以放到

一个数组里面,这个数组就叫做函数指针数组,循环里面直接调用就可以了;

函数指针数组就是在函数指针名字后面加上元素个数;

(2)接下来讲一下函数指针数组如何使用:以一个计算机的构建为例,这个计算机可以实现

简单的四则运算;下面是自定义函数和主函数的代码

下面的是函数

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 divi(int x, int y)
{
	return x / y;
}

下面主函数(注意除法的自定义函数不能直接使用div,本人亲测,div和库函数里面的div冲突)

void menu()
{
	printf("*****************************************\n");
	printf("**********1.add**************************\n");
	printf("**********2.sub**************************\n");
	printf("**********3.mul**************************\n");
	printf("**********4.divi**************************\n");
	printf("**********0.exit*************************\n");
}
int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	do {
		menu();
		printf("请选择\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入2个数字\n");
			scanf("%d %d", &x, &y);
			ret = add(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入2个数字\n");
			scanf("%d %d", &x, &y);
		    ret = sub(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入2个数字\n");
			scanf("%d %d", &x, &y);
			ret = mul(x, y);
			printf("%d\n", ret);
			break;
		case 4:
			printf("请输入2个数字\n");
			scanf("%d %d", &x, &y);
			ret = divi(x, y);
			printf("%d\n", ret);
			break;
		case 0:
			printf("退出计算器");
			break;
		default:
			printf("请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

思考分析简化:

 这个是一个普通的计算器,只有加减乘除法则运算;

这样看来,每个case都要重复,显示的有些冗余,这个时候可以使用函数指针数组;

int main()
{
	int input = 0;
	int x = 0;
	int y = 0;
	int ret = 0;
	int(*ptr[5])(int,int) = {NULL,add,sub,mul,divi};
	do
	{
		menu();
		printf("请选择\n");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入2个数字\n");
			scanf("%d %d", &x, &y);
			ret = ptr[input](x, y);
			printf("%d\n", ret);
		}
		else if (input == 0)
		{
			printf("退出计算器\n");
			break;
		}
		else
		{
			printf("选择错误,重新选择\n");
		}
	} while (input);
	return 0;
}

这个时候,引入数组,里面就是函数,因为要使我们输入的input和数组元素的下标相对应,

所以我们把第一个元素设置为NULL,这样我们选择哪个数字,就可以找到对应函数地址,使用这个

函数,这样函数的下标就是1,2,3,4了;ptr[input]直接找到对应的地址,使用这个函数

而且,如果想要增加法则,只需要增加数组元素就可以了,如果不是用这种数组,就需要

增加case语句,里面的内容还是需要重复,更加复杂,函数指针数组的优势就体现了出来。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

18个惊艳的可视化大屏(第12辑):智慧校园与教育方向

智慧校园可视化大屏通过数据可视化技术&#xff0c;将学校各个方面的数据信息进行展示&#xff0c;可以提高信息公开透明度、优化校园管理、提高学生教育质量和提高校内活动宣传效果等。 1提高信息公开透明度&#xff1a; 通过大屏幕展示校园各个方面的数据信息&#xff0c;可…

Golang Vs Java:为您的下一个项目选择正确的工具

Java 首次出现在 1995 年&#xff0c;由 James Gosling 和 Sun Microsystems 的其他人开发的一种新编程语言。从那时起&#xff0c;Java 已成为世界上最受欢迎和广泛使用的编程语言之一。Java 的主要特点包括其面向对象的设计、健壮性、平台独立性、自动内存管理以及广泛的内置…

【InternLM 实战营笔记】OpenCompass大模型评测

随着人工智能技术的快速发展&#xff0c; 大规模预训练自然语言模型成为了研究热点和关注焦点。OpenAI于2018年提出了第一代GPT模型&#xff0c;开辟了自然语言模型生成式预训练的路线。沿着这条路线&#xff0c;随后又陆续发布了GPT-2和GPT-3模型。与此同时&#xff0c;谷歌也…

击鼓传花游戏

有N个小朋友围成一圈玩击鼓传花游戏&#xff0c;将小朋友编号为1-N&#xff0c;从1号开始传花&#xff0c;每次传3个&#xff0c;拿到花的小朋友表演节目后退出。任给N&#xff0c;问最后一个表演的小朋友编号是多少&#xff1f;例如&#xff1a;输入5&#xff0c;从1号开始传花…

Java网络通信TCP

目录 TCP两个核心类 服务端 1.用ServerSocker类创建对象并且手动指定端口号 2.accept阻塞连接服务端与客户端 3.给客户端提供处理业务方法 4.处理业务 整体代码 客户端 1.创建Socket对象&#xff0c;并连接服务端的ip与端口号 2.获取Socket流对象&#xff0c;写入数据…

基于springboot+vue的智能学习平台系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

2024年阿里云2核4G配置服务器测评_ECS和轻量性能测评

阿里云2核4G服务器多少钱一年&#xff1f;2核4G服务器1个月费用多少&#xff1f;2核4G服务器30元3个月、85元一年&#xff0c;轻量应用服务器2核4G4M带宽165元一年&#xff0c;企业用户2核4G5M带宽199元一年。本文阿里云服务器网整理的2核4G参加活动的主机是ECS经济型e实例和u1…

备战蓝桥杯---状态压缩DP基础2之TSP问题

先来一个题衔接一下&#xff1a; 与上一题的思路差不多&#xff0c;不过这里有几点需要注意&#xff1a; 1.因为某一列的状态还与上上一行有关&#xff0c;因此我们令f[i][j][k]表示第i行状态为j,第i-1行状态为k的最大炮兵数。 因此&#xff0c;我们可以得到状态转移方程&…

一篇文章吃透整个JVM,JVM超详细笔记

这里写目录标题 JVMJVM执行流程JVM执行流程 JVM内存模型1.堆区&#xff08;Heap&#xff09;2.虚拟机栈&#xff08;JVM Stacks&#xff09;3.本地方法栈&#xff08;Native Method Stacks&#xff09;4.程序计数器&#xff08;Program Counter Register&#xff09;5.方法区/元…

机器学习 -- Octave基本操作

场景 Octave语言是一种高级数值计算和数据可视化的开源软件。它提供了一种方便的方式来执行数值计算、数据分析和可视化&#xff0c;特别是在科学和工程领域中。今天学习了一下Octave的基本操作&#xff0c;记录一下。 下载 去Octave官网下载即可。octave下载可自行下载。 …

学习人工智能:Sora技术报告Video generation models as world simulators,2024.2

原文链接&#xff1a; Video generation models as world simulators (openai.com) 摘要&#xff1a; 我们探索了在视频数据上大规模训练生成模型。具体来说&#xff0c;我们在可变片长、分辨率和纵横比的视频和图像上联合训练文本条件扩散模型text-conditional diffusion mo…

案例介绍:信息抽取技术在汽车销售与分销策略中的应用与实践

一、引言 在当今竞争激烈的汽车制造业中&#xff0c;成功的销售策略、市场营销和分销网络的构建是确保品牌立足市场的关键。作为一名经验丰富的项目经理&#xff0c;我曾领导一个专注于汽车销售和分销的项目&#xff0c;该项目深入挖掘市场数据&#xff0c;运用先进的信息抽取…

【Mybatis】快速入门 基本使用 第一期

文章目录 Mybatis是什么&#xff1f;一、快速入门&#xff08;基于Mybatis3方式&#xff09;二、MyBatis基本使用2.1 向SQL语句传参2.1.1 mybatis日志输出配置2.1.2 #{}形式2.1.3 ${}形式 2.2 数据输入2.2.1 Mybatis总体机制概括2.2.2 概念说明2.2.3 单个简单类型参数2.2.4 实体…

租房招聘平台新篇章:Java+SpringBoot技术革新

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

【iOS ARKit】协作Session

使用 ARWorldMap&#xff0c;能解决使用者再次进入同一物理空间时的AR 场景恢复问题&#xff0c;也能在多人之间共桌AR 体验&#xff0c;但这种共享并不是实时的&#xff0c;在载入ARWorldMap 后&#xff0c;设备新检测到的环境信息和使用者所做操作不会实时共享&#xff0c;即…

Avalonia学习(二十八)-OpenGL

Avalonia已经继承了opengl&#xff0c;详细的大家可以自己查阅。Avalonia里面启用opengl继承OpenGlControlBase类就可以了。有三个方法。分别是初始化、绘制、释放。 这里把官方源码的例子扒出来给大家看一下。源码在我以前发布的单组件里面。地址在前面的界面总结博文里面。 …

使用 MinIO 对象存储,创建一个类似网盘的应用

Linux 的 MinIO 对象存储 MinIO 介绍 MinIO 是一个对象存储解决方案&#xff0c;提供与 Amazon Web Services S3 兼容的 API&#xff0c;并支持所有核心 S3 功能。MinIO 可以部署在任何地方。 Amazon Simple Storage Service (Amazon S3) 是一种对象存储服务&#xff0c;提供…

HarmonyOS云端一体化组件之AGC应用管理

&#xff08;可选&#xff09;在AGC控制台创建同包名应用 如创建工程时&#xff0c;发现尚未在AGC控制台创建与工程包名相同的应用&#xff0c;可进行补充创建。 1.点击界面提示内的“AppGallery Connect”&#xff0c;浏览器打开AGC控制台“我的项目”页面。 2.点击选择您希…

springboot239华府便利店信息管理系统

华府便利店信息管理系统 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本华府便利店信息管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在…

非阻塞IO:提高应用程序的效率与性能

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…