C/C++中二维数组和指针关系分析

2023-05-16

        在C/c++中,数组和指针有着密切的关系,有很多地方说数组就是指针式错误的一种说法。这两者是不同的数据结构。其实,在C/c++中没有所谓的二维数组,书面表达就是数组的数组。我猜想是为了表述方便才叫它二维数组。

       在本文中,我也就叫它二维数组。在C/C++中,二维数组是数组的数组。数组的每一个元素是一个数组。说起来有点绕,大家都知道,一维数组也和指针那关比较密切,在本文中不重点阐述,下面就来阐述二维数组和指针之间到底存在着什么样的关系。

      一、二维数组一维化

           其实我这里也只是表述的方便才叫这么一个题目,我们怎么利用一个数组的访问方式来访问二维数组呢?下面来看一个具体的例子。

           首先,定义一个二维数组。

         

int iArr[2][3]={0,1,2,3,4,5};


我们可以用一个指向int型的指针变量来访问这个数组,下面的代码是将数组一维化:

int* p = iArr[0];

上面的iArr[0]就是代表第一个数组的首地址,由于二维数组在内存中的存储也是先行后列的方式,所以第二行也紧跟第一行之后,这样就可以用p来访问数组的元素值了,访问的方式有下标和指针方式。

	printf("%d,",p[3]);
	printf("%d\n",*(p+3));

最后输出的结果都是3。讲完了一维化之后,下面来继续看二维数组的函数名到底是什么意思?

 

        二、关于二维数组名的探索

      可能想当然的话,二维数组不就是一个二级指针吗?真是这样吗?下面用代码来验证下:

    

	int **pp = iArr;

       不出意外,会出现下面的编译错误:

      error C2440: “初始化”: 无法从“int [2][3]”转换为“int **”

      其实二维数组名是一个数组指针,那什么是数组指针?数组指针是指向一个数组首地址的指针,它实际上也是一种指针类型,类似于函数指针。它声明如下: 

	int (*pArr)[3]

      它说明pArr是一个数组指针,它指向的是一个数组元素为int类型并且数组元素的个数为3的一个数组指针,奇怪,中间的怎么还有一个括号是啥玩意?呵呵,这个括号还真是不可少的。少了它就变为另外一种类型了:指针数组。指针数组是数组类型,代表数组的每一个元素是指针类型,它声明如下:int  *pArr[3]。

      既然二维数组的数组名是指向第一行数组的首地址,我们也叫它行指针。那么我们可以用这种数组名或者指针来访问二维数组的元素。

    

int (*pArr)[3] = iArr;

下面,我要访问第一行第二列的元素,我可以用下面的代码来访问

	*(*(pArr+1) + 2)

也可以用数组名来访问:

*(*(iArr+1) + 2)

这种方式是不是一下很难看懂,为什么两个星号啊?下面就我的理解来作一下解释。仅以pArr做说明

首先,pArr是一个指向数组的指针,在这个指针上加减一个整数都是移动整行,而不是一个元素。比如说,pArr+1代表的现在指针已经指向第一行元素了,也就是实际中的第二行,而要取得指针所指的对象,就要用到解引用运算符*,所以*(pArr+1)就代表第一行数组,是整个这一行元素就取到了,那现在要取这一行的第二个元素,只须将指针再移动两个元素,即*(iArr+1) + 2,这样就指向了这个元素的地址,再解引用取得元素的值即可。说的有点啰嗦,或许有错误,望高手别喷就是了。

 

        三、作为函数参数

       一维数组名作为函数参数实际上是退化为指针,二维数组作为函数参数又有什么不同呢?下面举个例子说明。

 声明了如下函数:

void TestFun(int *pArr,int nlength)

假设,我用数组名和指向首个元素地址的指针作为传递参数,看看有什么效果?

TestFun(iArr,6);//“TestFun”: 不能将参数 1 从“int [2][3]”转换为“int *”
TestFun(&iArr[0][0],6);

直接传递数组名是编译通不过的。因为数组名是数组指针,而函数的参数是int*,两者的类型化完全不一样,所以不能转换。

而数组首元素的地址显然是int*类型,所以就能编译通过。

 

假设,我现在把这个函数的声明换一下,看看这两种传参的方法会出现什么情况?

现在的声明是:

void TestFun(void *pArr,int nlength)

还是这样传参,

	TestFun(iArr,6);
	TestFun(&iArr[0][0],6);

编译一下,居然都能通过了。在这里,第二种方式显然是没问题的,因为int*可以转化为void*。而第一种方式怎么就可以了呢?因为iArr是数组指针,当然也可以转换为void*啦。

 

四、后记

     天快黑了,要吃饭去了。本文就写到这里,文中有什么不对的地方,可以指出来,大家一起讨论。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++中二维数组和指针关系分析 的相关文章

随机推荐

  • 安装APK 免输入vivo、oppo密码

    2020 06 03补充 最优化版本 GitHub demo地址 apk下载地址 新建一个APP xff0c 使用Accessibility功能 监听vivo的 安装引用 界面用户输入 vivo密码 xff0c 后续 自动填写用 安装应用弹
  • Android logct中的线程ID

    针对logcat中的线程ID 进程ID过滤 好奇的是 线程ID 并不是Thread类里的ID 64 Override protected void onCreate Bundle savedInstanceState super onCre
  • Java Socket 服务端发送数据 客户端接收数据

    服务端 xff1a package com thinkgem wlw modules api test socket 64 Author zhouhe 64 Date 2019 4 8 9 30 import java io import
  • 百度移动软件开发面试题(20131018)

    1 new与malloc的区别 xff1f 分析 xff1a 一 new和malloc都是用于申请动态内存 new使用delete释放空间 xff0c malloc使用free释放 new和delete是C 43 43 中的运算符 xff0
  • RK3568 Debian10 AP6275S Bluetooth调试

    overlay etc profile d start blutooth sh start blutooth sh chmod 777 sys class rfkill rfkill0 state echo 0 gt sys class r
  • Java与VBA通讯实践

    1 DDE 动态数据交换 方式 VBA具有DDE能力 xff0c Java没有 网上搜索了一下 xff0c 有几个公司开发了这方面的类库 xff0c 可以使Java具有DDE能力 xff08 1 xff09 JavaDDE nevaobje
  • Linux下如何设置程序的开机自启动功能

    文章目录 Linux下设置程序开机自启动1 etc rc local2 etc profile d 3 使用 crontab 方式4 使用 systemd 服务测试代码 Linux下设置程序开机自启动 在最后 xff0c 我放了我测试时候要
  • vnc连接不上,vnc连接不上是为什么?原因详解

    vnc连接不上的原因 xff0c 服务器作为网站建设的常用设备 xff0c 在服务器运行过程中起到举足轻重的作用 用户在选择服务器是常用的方式有服务器租用 虚拟主机租用以及服务器托管 xff0c 通过进行文件以及数据的下载 上传等实现网站的
  • window10安装vnc无法使用,window10安装vnc无法使用的原因和解决办法

    window10安装vnc无法使用的原因 xff0c 服务器作为网站建设的常用设备 xff0c 在服务器运行过程中起到举足轻重的作用 用户在选择服务器是常用的方式有服务器租用 虚拟主机租用以及服务器托管 xff0c 通过进行文件以及数据的下
  • 企业信息化技术架构展望

    企业用户慢慢的从前期选用一些同行业成功的项目案例来复制 xff0c 或者选用一些知名的咨询公司提出的行业内通用方案 xff0c 转型为自己主动认真思考什么是自己需求 xff0c 什么是真正适合自己的信息化之路 做为企业信息技术架构设计 xf
  • Errors were encountered while processing: google-chrome-stable

    转自 xff1a http omtlab com errors were encountered while processing google chrome stable Many people facing this issue whi
  • virtualbox 命令

    VBoxManage命令详解 xff08 一 xff09 本人对vboxmange命令按我个人的理解作了解释 xff0c 由于本人水平有限难免有错误的地方 xff0c 希望大家帮我指正 VBoxManage v version 显示virt
  • 基于Springboot的物业管理系统_代码

    下载地址 1 1 课题背景 目的及意义 1 1 1 课题背景 互联网 43 改变着我们的生活 xff0c 在传统的社区物业服务领域 xff0c 在服务业主 提升社区服务 质量方面 xff0c 如何与互联网融合 xff1f 顶级互联网技术团队
  • eclips运行generatorConfig.xml文件生成代码

    描述 xff1a 如何通过eclips工具来运行 generatorConfig xml 文件来自动生成代码并获取数据 xff08 类似于mybaits逆向生成 xff09 xff1f mybatis generator generate
  • Spring源码(4)Context篇之AbstractApplicationContext(下)

    上一篇 Spring源码 4 Context篇之AbstractApplicationContext xff08 上 xff09 讲解了Spring的AbstractApplicationContext类refresh 方法 xff0c 前
  • java多线程 一个生产者和多个消费者

    生产者和消费者模式是面试时很容易被问到的一类题 xff0c 在平常的开发中也经常碰到 xff0c 比如在网游开发中 xff1a 用一个线程把收到的字节数据封装起来写到一个队列中 xff0c 然后用一个或多个线程从该队列中把数据读取出来再分发
  • Python最强装逼神技!微信远程控制电脑,想让你电脑关机就关机!

    今天带给大家一个非常有意思的 python 程序 xff0c 基于 itchat 实现微信控制电脑 你可以通过在微信发送命令 xff0c 来拍摄当前电脑的使用者 xff0c 然后图片会发送到你的微信上 甚至你可以发送命令来远程关闭电脑 程序
  • JAVA 在linux下面生成验证码异常问题

    应用部署到Linux下 xff0c 结果首页登录的验证码显示不出来 该验证码是用java的图片包来处理图片的 xff0c 后台日志报错 xff1a java lang NoClassDefFoundError sun awt X11Grap
  • 【PowerShell 一天一练】 3. 调用winrar解压

    如果你安装了 winrar 且安装在对应下面的路径 xff0c 可以尝试一下下面的代码 xff08 事实上我也是 copy 并修改自网上的代码 xff09 unrar 61 c Program files winrar unrar exe
  • C/C++中二维数组和指针关系分析

    在C c 43 43 中 xff0c 数组和指针有着密切的关系 xff0c 有很多地方说数组就是指针式错误的一种说法 这两者是不同的数据结构 其实 xff0c 在C c 43 43 中没有所谓的二维数组 xff0c 书面表达就是数组的数组