C/C++中二维数组和指针关系分析
在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*啦。
C/C++中二维数组和指针关系分析的更多相关文章
- c语言中双维数组与指针的那点事儿
说起c语言的指针,估计对c语言只是一知半解的同志们可能都会很头疼,尤其它跟数组又无耻的联系到一起的时候,就更加淫荡了!!! 怎么说呢,就是有一点规定:(或准则) 数组名可以看成是指向数组头元素的指针, ...
- 二维数组和指针(C语言)
二维数组和指针 二维数组和指针1.二维数组和数组元素的地址若有以下定义:int *p, a[3][4]; 1)二维数组a由若干个一维数组组成在C语言中定义的二维数组实际上是一个一维数组,这个一维数组的 ...
- C++中二维数组的动态分配
C++中二维数组的动态分配 作者: 来源:csdn博客 公布者:admin 时间:2009-04-23 13:55:03 点击:115 C++中一维数组的动态分配十分经常使用,但C++刚開 ...
- C/C++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法
本文转载自:https://blog.csdn.net/qq_33573235/article/details/79530792 1. 二维数组和指针 要用指针处理二维数组,首先要解决从存储的角度对二 ...
- 程序员之--C语言细节13(二维数组和指针,&*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)
主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_C ...
- C语言教学--二维数组和指针的理解
对于初学者对二维数组和指针的理解很模糊, 或者感觉很难理解, 其实我们和生活联系起来, 这一切都会变得清晰透彻. 我们用理解一维数组的思想来理解二维数组, 对于一维数组,每个箱子里存放的是具体的苹果, ...
- C语言--指向多维数组的指针和指针数组
#include <stdio.h> //void show(char *p[]); ]); int main(){ ][]={","abc","x ...
- 关于c语言二维数组与指针的个人理解及处理办法。
相信大家在学习C语言时,对一维数组和指针的理解应该是自信的,但是,我在学习过程中,看到网上一些博文,发现即便是参加工作的一些专业编程人员,突然碰到二维数组和指针的问题时,也可能会遇到难以处理的诡异问题 ...
- C指针 指针和数组 二维数组的指针 指针应用
直接到变量名标识的存储单元中读取变量的值--直接寻址 通过其他变量间接找到变量的地址读取变量的值--间接寻址 指针变量存放地址 显示变量的地址 指针变量使用前必须初始化,若不知指向哪,可先指向NULL ...
随机推荐
- lesson 18 Electric currents in modern art
lesson18 Electric currents in modern art electricity n. 电力:电流; electric adj. 电的:电动的; electronic adj. ...
- 博客美化—添加萌萌的live2D看板娘(不能再简单了)
看着很多博客都有live2D的萌萌哒看板娘,我闲着有空说干就干. 从参考博客的附件中下载资源文件 waifu.css waifu-tips.js live2d.js flat-ui.min.css// ...
- CPU设计学习-流水线
各种名词 标量流水线 超级流水线 超标量流水线与多发射技术 经典五级流水线 IF |Instruction Fetch,取指 ID |Instruction Decode,译码 EX |Execute ...
- tensorflow学习笔记(3)前置数学知识
tensorflow学习笔记(3)前置数学知识 首先是神经元的模型 接下来是激励函数 神经网络的复杂度计算 层数:隐藏层+输出层 总参数=总的w+b 下图为2层 如下图 w为3*4+4个 b为4* ...
- 基于Kubernetes(k8s)的RabbitMQ 集群
目前,有很多种基于Kubernetes搭建RabbitMQ集群的解决方案.今天笔者今天将要讨论我们在Fuel CCP项目当中所采用的方式.这种方式加以转变也适用于搭建RabbitMQ集群的一般方法.所 ...
- POJ 2826 An Easy Problem?!(线段交点+简单计算)
Description It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Be ...
- nodejs基础学习
一:复制官网的代码,建立一个简单的服务器 const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; ...
- ubuntu上的inpack测试
测试linpack 配置 配置linpack环境是整个过程中最麻烦的,也可能是因为我在配置的过程中出现了很多小问题吧.大概有3天的时间除了上课就在配置环境. 问题 总结起来问题和解决方法有这些 1.路 ...
- iOS开发多线程编程2 - NSOperation
1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用它的子类,使用NSOpera ...
- 【Linux】- CentOS查看IP
1.查询命令: ip addr 显示如图: 可以看到ens33没有inet这个属性,那么就没办法通过IP远程连接. 2.设置配置文件: vi /etc/sysconfig/network-script ...