C++指针和二维数组

在C++中,二维数组元素值在内存中是按行的顺序存放的,即先存二维数组的第一行数据,然后再存储第二行数据,一次类推,可以把它看成是一个特殊的一维数组。因此,与一维数组类似,可用指针变量来访问二维数组。我们可以像使用一维数组一样,对二维数组进行操作。但是那样非常麻烦,所以C++提供了关于二维数组的单独操作方法。

首先搞清楚三个概念:

1.二维数组行首地址

二维数组各元素按行排列可写成矩阵形式,若将第i行中的元素a[i][0])、a[i][1]… a[i][n]组成一维数组a[i](i=0, …,n),则有:

a[0] = (a[0][0], ..., a[0][n])

a[m] = (a[m][0], a[m][1], …, a[m][n]

因为数组名可用来表示数组的首地址,所以一维数组名a[i]可表示一维数组(a[i][0], a[i][1], a[i][2], ...,a[i][n])的首地址&a[i][0],即可表示第i行元素的首地址。因此,二维数组a的第i行首地址(即第i行第0列元素地址)可用a[i]表示。

一维数组的第i个元素地址可表示为“数组名+i”,因此一维数组a[i]中第j个元素a[i][j]的地址可表示为a[i]+j,即二维数组a中第i行第j列元素a[i][j]的地址可用a[i]+j来表示,而元素a[i][j]的值为*(a[i]+j)。

2.二维数组行地址

为了区别数组指针与指向一维数组的指针,C++引入了行地址的概念,并规定二维数组a中第i行地址用a+i或&a[i]表示。行地址的值与行首地址的值是相同的,即a+i = &a[i] = a[i] = &a[i][0],但两者类型不同,所以行地址a+i与&a[i]只能用于指向一维数组的指针变量,而不能用于普通指针变量,如下所示:

int a[3][3];

int *p = a + 0

对于上面两行语句,编译第二条指令时将会出错,编译系统会提示用户p与a+0的类型不同。如果要将行地址赋数组指针变量,必须用强制类型转换,如下所示:

int *p = (int *)(a + 0);

二维数组名a可用于表示二维数组的首地址,但C++规定该首地址并不是二维数组中第0行第0列的地址,即a != a[0][0],而是第0行的行地址,即a = a+0 = &a[0]。

3.二维数组的元素地址与元素值

知道了二维数组的行地址与行首地址后,可以讨论二维数组的元素地址。

因为a[i] = *(&a[i]) = *(a+1),所以*(a+1)可以表示第i行的首地址。因此二位数组第i行的首地址有3种表示方法,即a[i]、*(a+1)、&a[i][0]。

由此可推知,第i行第j列元素a[i][j]的地址有4种表示方法,即a[i]+j、*(a+i)+j、&a[i][0]+j、&a[i][j]。

而第i行第j列元素a[i][j]的值也有4种表示方法:*(a[i]+j)、*(*(a+i)+j)、*(&a[i][0]+j)、a[i][j]。

二位数组有关行地址、行首地址、元素地址、元素值的各种表示方法归纳:

第i行 行地址a+i、&a[i]第i行 首地址(第i行第0列地址)a[i]、*(a+i)、&a[i][0]元素a[i][j]的地址a[i]+j、*(a+i)+j、&a[i][0]+j、&a[i][j]第i行第j列元素值*(a[i]+j)、*(*(a+i)+j)、*(&a[i][0]+j)、a[i][j]

C++指针和二维数组

相关推荐