二维数组和双重指针

二维数组和双重指针

int a[3][4];

int **p;

如上是一个二维数组和一个双重指针,在普遍情况大多数人认为二维数组名a是可用一个双重指针来指向的,但是实际情况中这么做无法通过编译器。

二维数组和双重指针_第1张图片

为了弄清这么个问题,我们对二维数组和双重指针做一次分析。

二维数组

int a[3][4];

对于二维数组a我们要知道其原理,二维数组a是一个包含了3个元素的一维数组,这三个元素每一个都是包含了4个整型元素的一维数组,也即二维数组a是一个元素为一维数组的一维数组。

那么数组名a, a[0], &a[0][0]分别代表什么呢?如下图

二维数组和双重指针_第2张图片

图中分别打印出a, a[0], &a[0][0], a+1, a[1], &a[1][0], a[0]+1, &a[0][1]的值。

在理解二维数组过程中,我们可以将其当做一个一维数组来看,只是这个一维数组中的每个元素也是一维数组而已。

我们知道一维数组名为其首个元素的地址,也就是说,二维数组名a为首个元素的地址,也就是首行一维数组的地址。a[0]为首个元素,也就是首行数组名,其也为地址。

观察运算结果得出结论:

  1. a为首行地址
  2. a[0]为首行首个元素的地址
  3. &a[0][0]为整个数组首个元素的地址

以上三者地址完全相同,但是意义不同。

  1. a + 1为第二行数组的地址,加1就是往后偏移一位
  2. a[1]为第二行数组首个元素的地址
  3. &a[1][0]等同于2

另外a[0] + 1也与&a[0][1]是等同的,均为首行第二个元素的地址。

双重指针

双重指针就是指向指针的指针,想了解更多可以看下面这个博客。

双重指针的理解

回到最初得问题,为什么双重指针不能指向二维数组呢?

分析:二维数组名a本身也只是一个一维指针,其指向是一整个数组,而双重指针是指向指针的指针,与指向数组的指针是不能完全等价的,所以编译器不让通过。

所以想要指向一个二维数组,我们就可以定义一个指向数组的指针来指向它,即

二维数组和双重指针_第3张图片

这样编译器就不会报错。

int (*p)[4];是一个指针数组,首先p是一个指针,然后其指向一个包含四个元素的数组,这四个元素均为整型。阅读这样的定义要记住从内向外阅读,再从右向左绑定修饰符。

指针数组和数组指针

指针数组:int (* p)[10]; //p指向一个包含10个整数的数组

数组指针:int *p[10]; //p是一个数组,每个元素都是一个指向一个整数的指针

另外也可用数组的类型别名来指向二维数组

数组的类型别名

using int_array = int[4]; 等价于 typedef int int_array[4];

其中数据类型int_array表示一个包含4个整数的数组类型。

int_array p; //p为一个包含4个整数的一维数组

对二维数组a,有int_array *p = a; //p指向a中第一个包含4个元素的一维数组,p++则*p为a中第二行的数组

暂且记录在此,如有纰漏或错误,敬请批正。

你可能感兴趣的:(C与C++,c++,数组,指针)