概要
提示:C语言中的二维数组是一个由多个一维数组组成的数组,每个一维数组称为一个“行”,整个二维数组有多个行。每个行的大小相同,称为“列数”。
例如,一个3x3的二维数组可以表示为一个3行3列的矩阵:
1 2 3
4 5 6
7 8 9
整体架构流程
图8.20
前已述及,a[0]和*(a十0)等价,a[1]和*(a+1)等价,a[i]和*(a+i)等价。因此,a[0]+1和*(a+0)+1都是&a[0][1](即图8.20中的 2004)。a[1]+和*(a十1)十2的值都是&a[1][2](即图中的 2024)。请注意不要将*(a+1)+2错写成*(a+1+2),后者变成*(a+3)了,相当于 a[3]。
进一步分析,欲得到 a[0][1]的值,用地址法怎么表示呢?既然 a[0]+1和*(a+0)+1是a[0][1]的地址,那么,*(a[0]+1)就是 a[0][1]的值。同理,*(*(a十0)+1)或*(*a十1)也是 a[0][1]的值。*(a[i]+j)或*(*(a+i)+j)是 a[i][j]的值。务请记住 *(a+i)和 a[i]是等价的。
有必要对a[i]的性质作进一步说明。a[i]从形式上看是a数组中序号为i的元素。如果a是一维数组名,则a[i]代表a数组序号为i的元素的存储单元。a[i]是一个有确定地址的存储单元。但如果a是二维数组,则a[i]是一维数组名,它只是一个地址,并不代表一个存储单元,也不代表存储单元中的值(如同一维数组名只是一个指针常量一样)。a,a+i,a[i],*(a+i),*(a+i)+j,a[i]+j 都是地址。而*(a[i]+j)和*(*(a+i)+j)是二维数组元素 a[i][j]的值,见表 。
有些读者可能不理解,为什么a+1和*(a+1)的值都是2016呢?他们认为:a+1是地址,*(a+1)是该地址指向的存储单元中的内容,怎么会是同一个值呢?的确,二维数组中有些概念比较复杂难懂,要仔细消化,反复思考。
技术细节
我们接下来看一下这几行代码
例如,要访问数组 a 中的第一个元素 a[0][0]
,应该使用以下代码:
printf("%4d", *p);
要访问数组 a 中的第二个元素 a[0][1]
,应该使用以下代码:
printf("%4d", *(p+1));
要访问数组 a 中的第三个元素 a[0][2]
,应该使用以下代码:
printf("%4d", *(p+2));
要访问数组 a 中的第四个元素 a[0][3]
,应该使用以下代码:
printf("%4d", *(p+3));
z,应该使用 *p
的形式来访问数组 a 中的元素,而不是 p+a[0]
的形式。修改后的代码如下:
#include<stdio.h>
int main()
{
int a[3][4] = {{1, 3, 5, 7}, {9, 11, 13, 15}, {17, 19, 21, 23}};
int *p;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%4d", *p);
p++;
}
printf("\n");
}
return 0;
}
我们再看一下一个例子
#include<stdio.h>
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int b[3]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
printf("%d,%d",a[0],b[0]);
for(p=a[0];p<a[0]+12;p++)
{
if((p-a[0])%4==0) printf("\n");
printf("%4d",*p);
}
return 0;
}
6487520,1
1 3 5 7
9 11 13 15
17 19 21 23
小结
你们看一下我上面写的然后看一下1最下面的例子就会可能明白,如果你还是不懂可以找我私信,或者评论问就行,谢谢各位大佬的指出和知道,也谢谢各位的学者的支持