二维数组的传递和返回

news2024/11/15 18:03:56

指针和二维数组 

指针存储的是内存单元的地址,当使用引用运算符  *,或者变址运算符 [ ] 时才能将指针所指向的内存单元中的值取出。

指针有两个关键属性:

1.它存储的是内存地址

2.它存储的是什么类型变量的内存地址,这一点非常重要,这将决定对指针解引用时如何对它所指向的内存单元进行解读。

如果有这样定义的数组和指针变量

int *p;

int a[3]={1,2,3};

p=a;

那么它在内存中的图例是这样的:

                                             图一

变量名称实际就是内存地址的一个代号。

这里需要说明一下,数组名a其实不是一个变量,它是一个常量,即不可以进行加减操作,例如a++也就是a=a+1,这样的赋值操作是不允许的,这里只是为了说明方便称其为变量名。

数组地址的表达方式有以下几种:

a 表示数组a的首地址,也就是0x0000;

&a也可以表示数组的首地址,也是0x0000,

&a[0]也是数组元素的首地址,也是0x0000

例如:这些输出都将是数组a的首地址

 printf("%p\n",a);

printf("%p\n", &a);

printf("%p\n",&a[0]);

二维数组和指针

如果a是一个二维数组

int a[2][3]={{1,2,3},{4,5,6}};

并使用二级指针int **p指向它

int **p;

p=a;

二维数组a[2][3]是一个2行3列的矩阵,但是那只是方便人们理解,在计算机内存中没有二维,都是一维,它仍然是线性存储的。此时,内存中的分布是这样的。

                                           图二

       这样对指针p赋值的话,编译器会给出警告,因为p和a的类型不同,也就是p+1和a[1]指针向后移动的内存单元数不同。例如这里,p存储的是指针变量的地址也就是指向整形指针的指针变量,而整形指针占4个字节的位置,所以p+1将指向0x0004。而a是二维数组,它的元素是一个一维数组,长度为12个字节,a[1]将指向0x000C。

二维数组的首地址表示方法:

以下几种表示方法都可以表示首地址

a

&a

a[0]

&a[0]

但是要注意,二维数组的a[0]和一维数组中的a[0]不一样。

如图一所示,一维数组的元素是整形变量,它的a[0]是整形值1。

如图二所示,二维数组的元素是一个一维数组,也就是说,每个元素的长度是3*4=12个字节。a[0]表示的是一维数组的地址,也就是指向一维数组的指针,例如这里是0x0000,那么a[1]将是0x000C。

p是一个二级指针,将二维数组a的首地址赋值给它,那么它存储的地址将是0x0000。对p解引用一次*p,当然就取出了0x0000中的值,也就是1,如果执行语句printf(“%d”,(int)*p);  那么得到的结果是1,但这并不是二维数组的正确打开方式。

当对p再次解引用的时候,就出错了(*(*p)),它表示取出内存地址0x0001中的值,那将什么也不是,当然会出错。而且p每增加1,内存地址+4,a每增加1,内存地址+12,所以,无法直接使用二级指针p来正确操作二维数组a。

如何使用指针操作二维数组呢?

可以定义特殊的二级指针,int (*p)[3]来指向二维数组。它是一个二级指针,并且说明了一维数组中元素的个数是3个,这样p指针每+1,内存地址加3*4=12。()不能去掉,因为*比[]运算符优先级低。

p=a;   //p=0x0000

p++;   //p=0x000C

显示数组元素可以使用这几种写法:

p[行][列]

(* (p+行))[列]

*(* (p+行)+列)

以下程序段将可以正确打印二维数组

#include <stdio.h>


main()
{

	int i, j;
	int a[2][3] = { 
		{1,2,3},
	    {4,5,6} 
	};
	//定义一个特殊的二级指针
	int(*p)[3];

	p = a;

	printf("在主函数中打印数组a[2][3]\n");
	for (i = 0; i < 2; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("% d ", p[i][j]);
		}
		printf("\n");
	}

}

如何将一个二维数组作为参数传递给函数:

形式参数要写明数组的数据类型,例如这里是int ,并且是指针变量,而且每行有3个数据,即:

int(*p)[3] ,这样内存每+1,内存单元增长3*4=12

然后,可以在函数中像使用普通数组那样使用指针变量p调用数组中的元素,例如p[i][j]

#include <stdio.h>


func(int(*p)[3])
{
	int i, j;

	printf("\n在函数func中打印数组a[2][3]\n");
	for (i = 0; i < 2; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("% d ", p[i][j]);
		}
		printf("\n");
	}

}


main()
{
	int a[2][3] = { 
		{1,2,3},
	    {4,5,6} 
	};

	func(a);
}

如何返回一个二维数组

首先,函数的返回值类型要是一个二级指针的形式:

int **func2()

然后,函数的返回值用一个特殊的二级指针接收,改指针指出了每行元素的个数,例如:

int (*p)[3];

表示是一个整型的二级指针,它每行的数据是3个,也就是p每加1,内存单元增长12个。

#include <stdio.h>

int **func2()
{
	static int a[2][3] = {
	{1,2,3},
	{4,5,6},
	};

	return a;
}


main()
{

	int i, j;
	int a[2][3] = { 
		{1,2,3},
	    {4,5,6} 
	};
	//定义一个特殊的二级指针
	int(*p)[3];


	p = func2();
	printf("\n在主函数中打印函数传递过来的数组\n");
	for (i = 0; i < 2; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("% d ", p[i][j]);
		}
		printf("\n");
	}

}

其实这里用一级指针也可以正确返回二维数组的首地址,但是要在主函数中用带有维度的特殊二级指针正确转化一下。

但是这种返回方式编译器会给出警告,如果不想看到警告信息,可以这样返回二维数组:

#include <stdio.h>

int  (*func3())[3]
{
	static int a[2][3] = {
	   {1,2,3},
	   {4,5,6},
	};

	return a;
}

main()
{

	int i, j;
	int a[2][3] = { 
		{1,2,3},
	    {4,5,6} 
	};
	//定义一个特殊的二级指针
	int(*p)[3];

	p = func3();

	printf("\n在主函数中打印函数传递过来的数组\n");
	for (i = 0; i < 2; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("% d ", p[i][j]);
		}
		printf("\n");
	}

}

这样,在返回值中指出了数组的维度,在接收值中也有相同的类型和维度,也就是指针类型完全相同,编译器就不会给出警告了。

传递二维数组,关键是要传递正确的数组首地址,并正确解读其中包含的维度。

参考链接:

https://blog.csdn.net/qq_33573235/article/details/79530792

https://www.cnblogs.com/zhixin/articles/3396789.html

https://blog.csdn.net/qq_39090164/article/details/79425247

https://www.cnblogs.com/qingergege/p/6917913.html

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

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

相关文章

盛元广通粮油质量检测实验室管理系统

近年来对于食品安全问题层出不穷&#xff0c;为提高粮食检测中心管理水平&#xff0c;关系到千千万万的消费者的健康饮食问题&#xff0c;粮油作为老百姓日常生活饮食必需品、消耗品&#xff0c;需从源头上对粮食在本省&#xff08;区、市、县&#xff09;不同粮食品种检测检测…

vulhub靶场-matrix-breakout-2-morpheus

下载&部署 从官网中下载 https://www.vulnhub.com/entry/matrix-breakout-2-morpheus,757/ 下载完成后&#xff0c;在vmware中打开&#xff0c;选择刚刚下载的ova文件 vmware打开文件后需要将刚导入的机器重新启动 再检查下网卡是否是和kali在同一张网卡下就可以开始打靶了…

使用Amazon Bedrock托管的Claude3 学习中国历史

最近被Amazon Bedrock托管的Claude3 刷屏了&#xff0c;那么先简单介绍下什么是Claude 3。 Claude 3是Anthropic 推出了下一代 Claude模型&#xff0c;针对不同用例进行优化的三种先进模型&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 和 Claude 3 Opus&#xff0c;使用户能够…

【Hadoop大数据技术】——HDFS分布式文件系统(学习笔记)

&#x1f4d6; 前言&#xff1a;Hadoop的核心是HDFS&#xff08;Hadoop Distributed File System&#xff0c;Hadoop分布式文件系统&#xff09;和MapReduce。其中&#xff0c;HDFS是解决海量大数据文件存储的问题&#xff0c;是目前应用最广泛的分布式文件系统。 目录 &#x…

【SpringCloud微服务实战03】Nacos 注册中心

一、Nacos安装 官方文档安装Nacos教程:Nacos 快速开始 这里安装的是1.4.7版本,安装之后访问http://127.0.0.1:8848/nacos 管理界面如下:(用户名:nacos,密码:nacos) 二、Nacos服务注册和发现 1、在父工程中配置文件pom.xml 中添加spring-cloud-alilbaba的管理依赖:…

模型分析与偏差和方差

在创建一个机器学习系统&#xff0c;当我们的模型出现问题时&#xff0c;我们需要去找到最优的方式&#xff0c;能解决我们的问题&#xff0c;这时我们就需要会去诊断问题。 模型评估(Evaluating a model)&#xff1a; 1.训练集和测试集判断&#xff1a; 我们一般把数据组的前…

LeetCode - 寻找数组的中心

先学习一下前缀和吧 LCR 012.寻找数组的中心LCR 012. 代码解析 在读题读到左侧元素之和等于右侧所有元素之和的时候&#xff0c;我觉得可以用前缀和&#xff0c;然后结合下面的示例&#xff0c;模拟了一下发现确实可以。 我的想法是搞两个数组&#xff0c;一个来存从左到右数…

MySQL索引+常见问题详解

文章目录 字典的数据部分字典的索引部分数据页索引页MySQL单表最大数据容量2000万&#xff1f;MySQL为什么采用B树&#xff1f;聚簇索引 / 非聚簇索引回表 / 索引覆盖为什么建议自增主键索引下推 网络上的讲述MySQL索引的文章太多了&#xff0c;我打算换个角度来说。我们尝试着…

物奇平台超距断连无蓝牙广播问题解决方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资料, 物奇平台超距断连无蓝牙广播问题解决方法 一 问题反馈 二解决方法: 1 运行流程分析 对应代…

八、软考-系统架构设计师笔记-系统质量属性和架构评估

1、软件系统质量属性 软件架构的定义 软件架构是指在一定的设计原则基础上&#xff0c;从不同角度对组成系统的各部分进行搭配和安排&#xff0c;形成系统的多个结构而组成架构&#xff0c;它包括该系统的各个构件&#xff0c;构件的外部可见属性及构件之间的相互关系。 软件架…

盘点2024年2月Sui生态发展,了解Sui近期成长历程!

2024年2月喜迎中国春节&#xff0c;Sui生态发布多条重要公告&#xff0c;生态建设积极推进。例如&#xff0c;Sui上TVL突破5亿美元跻身DeFi榜单前十名和最活跃链前五名&#xff1b;Ondo宣布将其原生稳定币USDY带入Sui生态&#xff1b;Sui与Thrive合作推出ThinkSui平台&#xff…

2024年品牌推广:构建品牌生态圈与注重品牌故事和文化传播

在全球经济深度融合、数字化浪潮汹涌澎湃的2024年&#xff0c;品牌推广的策略与模式正经历着前所未有的变革。在这一背景下&#xff0c;构建品牌生态圈和注重品牌故事与文化传播&#xff0c;成为了企业提升品牌竞争力和市场占有率的重要手段。 一、2024年市场经济分析与现状 …

安装YOLOv8

1.创建、激活虚拟环境 conda create --name yolov8 python conda activate yolov8 2.安装YOLOv8 pip install ultralytics 3.在官方网页中下载YoloV8的所有的代码、并且解压&#xff1a; 官方网页&#xff1a;https://github.com/ultralytics/ultralytics/ultralytics 4.进入…

聚道云软件连接器3月新增应用/产品更新合集

3月更新概要 新增应用&#xff1a; 应用1&#xff1a;华为云welink 应用2&#xff1a;易宝支付 应用3&#xff1a;励销云CRM 应用4&#xff1a;分贝通 应用5&#xff1a;灵当CRM 新增&更新功能 1、【流程】中增加流程树状管理 新增应用 应用1&#xff1a;华为云wel…

全面认识计算机操作系统(二)

目录 一、操作系统的诞生 相关概念&#xff1a; 1. 手工操作阶段 2. 脱机输入 / 输出阶段 &#xff08;1&#xff09;脱机输入技术 &#xff08;2&#xff09;脱机输出技术 3. 单道批处理阶段 4. 多道批处理阶段 5. 分时技术产生 6. 实时系统产生 二、现代操作系统的…

学校里的软件测试专业技能到底怎样,为什么应届生都很难找工作?

大家好&#xff0c;今天和以为在学校教软件测试的老师聊了天&#xff0c;主要聊的主题是-为什么现在大专生就业这么困难。主要总结以下几点&#xff01; 一是受当下大环境的影响&#xff08;比如疫情、俄乌、单边主义等&#xff09;&#xff1b;二是今年的应届生实在太多&…

客户案例|100M 768 维向量数据,Zilliz Cloud 稳定支持 Shulex VOC 业

日前&#xff0c;国际化 VOC SaaS 公司数里行间&#xff08;Shulex&#xff09;将上亿数据量的核心业务从开源向量数据库 Milvus 迁移至全托管的向量数据库云服务 Zilliz Cloud。 相比于 Milvus&#xff0c;Zilliz Cloud 实现了 Shulex VOC 评论分析洞察报告生成速度 30% 的提升…

伊芙丽签约实在智能,实在Agent数字员工助力品牌效能飙升

近日&#xff0c;国内知名时尚女装品牌伊芙丽与实在智能达成合作&#xff0c;引入业内领先的平台级自动化产品实在Agent数字员工——取数宝&#xff0c;自动获取天猫、淘宝、抖音等线上平台营销数据&#xff0c;开启全域化营销的“提效之旅”。 实在Agent智能体 伊芙丽集团成立…

2024年AI辅助研发趋势:AI辅助科技发展

目录 前言 一、AI辅助研发的技术进展 &#xff08;一&#xff09;深度学习在研发中的应用 &#xff08;二&#xff09;强化学习在研发中的应用 &#xff08;三&#xff09;生成模型在研发中的应用 &#xff08;四&#xff09;技术如何推动研发效率的提升 二、2024人工智…

谷歌浏览器如何使用词令官网直达快速打开微博官方网站?

谷歌浏览器如何使用词令官网直达快速打开官方网站&#xff1f; 1、电脑上打开谷歌浏览器&#xff0c;选择打开词令官网直达网站&#xff1b; 2、打开词令关键词口令直达网站&#xff1b; 3、输入网站名称或点击热门历史词令中的网站名称&#xff1b; 4、输入词令搜索直达进入微…