二维数组与二级指针

关于二维数组与二级指针那些你必须知道的事

首先,来看一个例子

#include <iostream>

using namespace std;

int main(void)
{
	int **p;
	p=new int*[5];
	for(int i=0;i<5;i++)
	{
		p[i]=new int[5];
	}
	return 0;
}

  不严格地说(等下细讲),以上代码实现了一个二维数组,我们在访问其中某一个元素的时候,就可以使用p[x][x]的形式来实现;相信聪明的大家不难看出,其实现原理是首先定义一个二级指针使它指向一个 指针数组 ,然后使用循环依次让指针数组里面的指针指向一片int类型的数组,大概是这样的:
在这里插入图片描述
  这样的数据结构不仅仅可以实现二维数组的功能,还可以实现"不等长"数组(每个一级指针申请的空间大小不全一样),如此具有迷惑性外表的二级指针,让我很久以来认为二维数组的数组名不过是一个二级指针,而传统的二维数组只不过编译器限制二级指针指向的 指针数组 中的指针元素所指向的空间大小必须是一样的。

一个error

  某一天,我在函数传参的时候,将一个二维数组作为实参传递,把形参写作二级指针,代码大概是这样的:

#include <iostream>

using namespace std;

void demo(int **array)
{
	return;
}

int main(void)
{
	int array[5][5];
	demo(array);
	return 0;
}

然后…
“[Error] cannot convert ‘int (*)[5]’ to ‘int**’ for argument ‘1’ to ‘void demo(int**)’”

嗯,我是解析

  先说结论:二维数组名不是二级指针,而是一个数组指针
  关于二级指针,其实就是指向指针的指针,在上面我用二级指针指向一个 指针数组 是合法的,其值就是 指针数组 第一个元素的地址,而第一个元素是一个指针,那么就是指向指针的地址,在通过下标找寻元素的时候,其实质是先找到所谓"行"(找到一个指针),然后通过第二个下标找到该指针指向的第几号元素完成索引。
在这里插入图片描述
  那么二维数组名是什么呢?
  在error部分我们需要将代码修改成这样便可以正常运行:

#include <iostream>

using namespace std;

void demo(int (*array)[5])//修改的这里 
{
	return;
}

int main(void)
{
	int array[5][5];
	demo(array);
	return 0;
}

  应证了上面的结论
  在c/c++中,多维数组的构成其实是通过数组嵌套构成更高维的数组,比如,二维数组中每一个元素都是一个一维数组,五维数组的每一个元素都是一个四维数组,那么,数组名是指向首元素的指针,于是二维数组名就是一个指向一维数组的指针(int (*a)[x]),同样的,多维数组名其实就是一个指向维度-1的数组指针(int(*a)[x][x][x]…)。

指针数组与数组指针

  指针数组与数组指针根本区别原因是:C语言中,[]运算符优先级大于*运算符优先级
  指针数组是一个数组,这个数组的每一个元素都是一个指针。
  数组指针是一个指针,这个指针指向的是 一个数组 这里要注意的是,是指向整个数组,而不是指向数组的第一个元素,否则就与二维数组名不是二级指针矛盾,数组指针大概是这样的:
在这里插入图片描述
  我们在定义一个数组指针的时候,必须指定其所指向的数组的宽度,这样在数组指针进行行变换的时候编译器就知道该跨越多少个元素去找到所期望的哪一行数组(数组是一片连续的存储空间,这里抽象成为一个矩阵)。
  最后一个例子:int (*a)[5],a代表了一个指向拥有5个元素的数组,那么a[2][3]就是告诉编译器,我要找到一个地址从首元素跨越2x5+3个sizeof(int)的那个元素。
在这里插入图片描述
  写在最后:目前很多c语言教材将二维数组名直接抽象为一个二级指针,这种做法也许便于理解,但是却不是真正的答案。
在这里插入图片描述
本文仅个人观点,如有错误,感谢指正!

越是接近真理,便愈加发现真理的迷人。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值