你了解C语言中的数组指针和函数指针吗?

news2024/11/24 0:21:16

如题,本篇文章重点讲解C语言中的数组指针和函数指针。这2种指针其实都不是很常用,个人感觉使用起来代码的可读性不是很高,但是还是需要了解一下。
数组指针&&函数指针

数组指针

数组指针,即指向数组的指针,是用来存放数组的地址的。那如何取出数组的地址呢?直接&数组名即可。如:

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
&arr; // 取出数组的地址

这里的&arr,就能得到数组的地址。如果我们想把它存起来,就需要一个数组指针变量。写法如下:

int (*p)[10] = &arr;

解释一下。首先,括号是不能省略的。如果写成int *p[10],就是个指针数组了,这个数组可以存放10个整形指针变量。

括号把*和数组指针变量名p括起来,此时p会优先和*结合,就是一个指针。把(*p)去掉,剩下的int [10]就是数组的类型,表示这个数组指针变量指向的数组存储int类型的数据,容量是10。

这个数组指针类型是:把变量名p去掉后的int (*)[10]

数组指针应该如何使用呢?这里举一个二维数组传参的例子。比如,我们有一个三行五列的二维数组,请你写一个函数,使用指针来打印这个数组里的值。

int arr[3][5] = {{1,2,3,4,5}, {11,22,33,44,55}, {111,222,333,444,555}};
Print(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0])/sizeof(arr[0][0]));

函数Print的形参应该如何写呢?如果是用一个二维数组接收,我相信大家应该是会写的,但是如果要用指针来接收呢?这个指针是什么类型的呢?

数组传参,数组名表示首元素的地址,二维数组的首元素就是第一行!也就是说,二维数组arr的数组名表示第一行的地址,而第一行是一个含有5个int的一维数组。再换句话说,arr作为二维数组的数组名,表示的是一个含有5个int的一维数组的地址,所以需要一个数组指针来接收,这个数组指针指向一个含有5个Int的一维数组!

void Print(int (*p)[5], int r, int c)
{}

函数体实现的关键就是,如何使用数组指针p来遍历原来的二维数组arr。其实呀,既然是数组名作为参数传过来,就可以当成正常的数组那样使用,比如p[i][j]其实就表示第i行第j列的元素。在C语言中,a[i]就等价于*(a+i),所以p[i][j]就等价于*(*(p+i)+j),所以一下2种实现是等价的。

void Print(int(*p)[5], int r, int c)
{
	for (int i = 0; i < r; ++i)
	{
		for (int j = 0; j < c; ++j)
		{
			// 写法1
			//printf("%d ", p[i][j]);
			// 写法2
			printf("%d ", *(*(p + i) + j));
		}
		printf("\n");
	}
}

如果用数组指针的角度来理解*(*(p+i)+j),应该怎么想呢?p是数组第一行的地址,p+i就是数组第i行的地址,*(p+i)就拿到了数组的第i行,相当于拿到了数组第i行的数组名,也就是数组第i行第一个元素的地址。那么,*(p+i)+j就是数组第i行第j个元素的地址,*(*(p+i)+j)就是数组第i行第j个元素。

函数指针

函数指针和数组指针非常像。数组指针是指向数组的指针,函数指针则是指向函数的指针。也就是说,函数指针是用来存放函数的地址的。

如何取得函数的地址呢?有2中方法:

  1. 函数名就表示函数的地址。
  2. &函数名也表示函数的地址。

比如:

int Add(int x, int y)
{
	return x + y;
}

对于Add函数,Add&Add都能得到它的地址。那么,存放这个地址的函数指针应该如何写呢?

int (*p1)(int, int) = Add;
int (*p2)(int, int) = &Add;

和数组指针非常类似。用括号把*p括起来,表示p是一个指针,去掉(*p)后得到的int (int, int)就是这个指针指向的函数的类型,即参数是int, int,返回类型是int的函数。

这个函数指针类型名是:把变量名去掉后的int (*)(int, int)

使用函数指针可以调用函数,有2种调用方式:

  1. 不解引用,直接调用:p(3, 5)
  2. 解引用后再调用:(*p)(3, 5)

比如,以上的代码可以这么写:

int (*p)(int, int) = Add;
int ret1 = p(3, 5);
int ret2 = (*p)(3, 5);

其实这个解引用操作没啥用,你哪怕写int ret2 = (***************p)(3, 5);,效果和不加*是一样的。

总结

  1. 数组指针是指向数组的指针,数组指针类型由3部分构成:用括号把变量名和*括起来表示是一个指针,左边写指针指向的数组存储的元素的类型,右边用方括号表示指向的数组的容量。
  2. 函数指针是指向函数的指针,函数指针类型由3部分构成:用括号把变量名和*括起来表示是一个指针,左边写指针指向的函数的返回类型,右边用圆括号表示函数的形参列表。
  3. 这两货确实挺像。

感谢大家的阅读!

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

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

相关文章

JavaScript对象类型之Array及Object

目录 一、Array &#xff08;1&#xff09;语法 &#xff08;2&#xff09;API 二、Object &#xff08;1&#xff09;语法 &#xff08;2&#xff09;特色&#xff1a;属性增删 &#xff08;3&#xff09;特色&#xff1a;this &#xff08;4&#xff09;特色&#xf…

公司测试员用例写得乱七八糟,测试总监制定了这份《测试用例编写规范》

统一测试用例编写的规范&#xff0c;为测试设计人员提供测试用例编写的指导&#xff0c;提高编写的测试用例的可读性&#xff0c;可执行性、合理性。为测试执行人员更好执行测试&#xff0c;提高测试效率&#xff0c;最终提高公司整个产品的质量。 一、范围 适用于集成测试用…

SAP MDG —— 使用DIF导入物料主数据 Part3 进阶篇

文章目录关于使用DIF处理物料主数据的相关信息IDOC 缩减IDOC 扩展物料编码的主键映射 Key Mapping主键映射和内部给号其他主键的主键映射值映射 Value Mapping将物料主数据导出为IDoc文件 - MATMAS / CLFMAS错误处理本章小结关于使用DIF处理物料主数据的相关信息 IDOC 缩减 场…

机器学习:基于KNN对葡萄酒质量进行分类

机器学习&#xff1a;基于KNN对葡萄酒质量进行分类 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏…

网盘工具助力律师团队文件管理

律师的日常工作离不开文件管理。文档管理对于律师而言是一门必修课&#xff0c;这也是日积月累的工作。良好的文件管理习惯可以帮助我们让工作流程化、标准化&#xff0c;助力知识管理&#xff0c;避免职业风险&#xff0c;提升团队工作效率。 好用的文件管理工具也可以帮助律师…

Python 实验三 控制语句

1.从键盘接收整数的一百分制成绩&#xff08;0到100)&#xff0c;要求输出其对应的成绩等级A-E。其中&#xff0c;90分&#xff08;包含&#xff09;以上为A&#xff0c;80-89&#xff08;均包含&#xff09;分为B&#xff0c;70-79(均包含&#xff09;分为C&#xff0c;60-69&…

[网络安全] Windows Server 设置文件屏蔽防止黑客利用漏洞上传特定类型的非法文件

我在负责网站运维期间&#xff0c;遇到过一次黑客利用网站内使用的开源文件上传工具漏洞上传非法文件&#xff08;可执行脚本&#xff09; 我是通过设置文件屏蔽来防止此类事件的再次发生。特在此做下记录。 文章目录前言一、黑客是怎么攻击我的二、我是怎么防范的2.1 Windows …

我学习网络安全的心得

我的学习心得&#xff0c;我认为能不能自学成功的要素有两点。 第一点就是自身的问题&#xff0c;虽然想要转行学习安全的人很多&#xff0c;但是非常强烈的想要转行学好的人是小部分。而大部分人只是抱着试试的心态来学习安全&#xff0c;这是完全不可能的。 所以能不能学成并…

Matplotlib 二维图像绘制方法

Matplotlib 二维图像绘制方法 介绍 Matplotlib 是支持 Python 语言的开源绘图库,因为其支持丰富的绘图类型、简单的绘图方式以及完善的接口文档,深受 Python 工程师、科研学者、数据工程师等各类人士的喜欢。本次实验课程中,我们将学会使用 Matplotlib 绘图的方法和技巧。…

GitHub的简介与Idea集成Git

六大基础功能 &#xff1a; 创建远程库、代码推送&#xff08;Push&#xff09;、代码拉取&#xff08;Pull&#xff09;、代码克隆&#xff08;Clone&#xff09;、SSH免密登录、Idea集成GitHub GitHub 网址&#xff1a;https://github.com/ 1.创建远程仓库 登录后的页面右上…

亚马逊云科技帮助BMW Financial Services设计和构建数据架构

BMW Group和亚马逊云科技于2020年宣布达成全面战略合作。在re:Invent2019上&#xff0c;BMW和亚马逊云科技展示了新的云数据中心平台&#xff0c;先是大致介绍了不同的数据平台原型&#xff0c;然后介绍了构建BMW Group云数据中心的过程。Amazon Data Lab使用亚马逊云科技的云数…

Volatile关键字的作用探究

前言 今天下午BOSS上投了个简历小试了一波水&#xff0c;结果被问到一个知识点volatile关键字的作用&#xff0c;我回答了线程的可见性&#xff0c;另一个死活想不起来是什么&#xff0c;当回到工位上看了眼笔记&#xff0c;才想起来。这种知识点其实平时使用的频率还是挺高的…

Phaser笔记-scene中的preload、create、update、player、键盘控制

一般phaser最简单的配置文件如下&#xff1a; let config {type: Phaser.AUTO,width: 800,height:600,scene: {preload: preload,create: create,update: update},physics:{default: arcade,arcade: {gravity: { y: 300},debug: false}}};其中scene有3个函数&#xff1a;prel…

CI570 3BSE001440R1适用于数字功能需求较多的设计

CI570 3BSE001440R1适用于数字功能需求较多的设计 尽管纯硅的CMOS 制程被认为仅适用于数字功能需求较多的设计&#xff0c;而不适用于以模拟电路为主的射频IC 设计&#xff0c;不过历经十几年的努力后&#xff0c;随着CMOS 性能的提升、晶圆代工厂在0.25mm 以下制程技术的配合、…

解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题

一、僵尸进程问题 在docker里&#xff0c;使用selenium爬虫&#xff0c; webdriver quit后&#xff0c;会产生很多僵尸进程。docker run -it -v /home/blackip:/home/blackips/ selenium:1.0python3 linux_black_ip.pytop查看僵尸进程&#xff1a;ps -ef | grep defunct查看…

微服务+springcloud+springcloud alibaba学习笔记【Ribbon的使用】(4/9)

Ribbon的使用 4/91、Ribbon负载均衡1.1 Ribbon简介1.2 Ribbon功能1.3 使用Ribbon:1.3.1 Ribbon常用负载均衡算法1.3.2 使用Ribbon1.3.3 ribbon的轮询算法原理1.3.4 手写一个负载均衡轮询算法1.3.5 启动服务,测试1、Ribbon负载均衡 1.1 Ribbon简介 Spring Cloud Ribbon是基于N…

Nestjs实战干货-概况-管道-Pipes

管道 带上装饰器 Injectable() 并实现了 PipeTransform 接口的类&#xff0c;就是管道。 管道有 2 个典型的应用场景&#xff1a; 数值转换&#xff1a;将输入的参数转换成目标类型&#xff0c;例如&#xff0c;string to number。 数值校验&#xff1a;对输入的参数进行校验…

记一次 MySQL 主从同步异常的排查记录,百转千回

本文主要内容如下&#xff1a; 一、现象 最近项目的测试环境遇到一个主备同步的问题&#xff1a; 备库的同步线程停止了&#xff0c;无法同步主库的数据更改。 备库报错如下&#xff1a; 完整的错误信息&#xff1a; Relay log read failure: Could not parse relay log even…

一文读懂【Git 工作流】

文章目录一、Git分支管理二、Git日志规范三、Git Flow工作流一、Git分支管理 我们在实际工作中会创建很多分支以便于不同场景下的开发&#xff0c;但是如果没有分支规范就会造成分支杂乱&#xff0c;大家往往也搞不清楚某一个分支是在做什么&#xff0c;下面我们就介绍一下我们…

车企围攻整车OS,这张“新王牌”怎么打?

今年2月23日&#xff0c;梅赛德斯--奔驰发布了打造自有操作系统MB.OS的具体计划&#xff0c;该操作系统将在本年代中期随全新梅赛德斯-奔驰模块化架构&#xff08;MMA&#xff09;平台推出&#xff0c;预计2025年用户将能体验到它的强大功能。 据悉&#xff0c;基于覆盖芯片到…