如何看待一维数组以及二维数组的数组名、首元素、数组地址

一维数组

定义一个数组:int a[5];

此处,a,&a[0]以及&a做右值时在数值上是完全相同的,但含义不同。

数组名a只能做右值,不能做左值。做右值是表示数组首元素首的地址,同&a[0],如:

定义一个int *类型指针int * p,此时p=a和p=&a[0]完全是一个效果,一个意思。

&a[0]即数组首元素首地址,只能做右值,同数组名a做右值。

而&a,表示的则是整个数组的地址,其本身是一个常量,也只能做右值。

注意a,&a[0]以及&a都是只能做右值的常量,且单纯从值这个角度看他们都是相等的,但含义千差万别,a和&a[0]是一样的,都表示int *类型的指针,而&a则表示为int *[5]的指针,即指向一个int型、含5个元素的数组的指针。

含义的不同令其在参加指针运算时所表现的特征不同:

*a和*(&a[0])一样,都表示第0个元素a[0],*(a+1)和*(&a[0]+1)一样,都表示a[1],它们每加1就表示加了sizeof(int)个字节;而(&a+1)则表示在数组a的地址的基础上加了sizeof(a)个字节数,即加了20个字节。此时访问*(&a+1)会出现数组越界的问题。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二维数组

定义一个二维数组:int a[2][3];

表示定义了一个数组,数组名叫a,这个数组有两个元素a[0]和a[1],这两个元素均为一维数组,。

其中a[0]是第一个一维数组的数组名(注意一定要将a[0]看做一维数组的数组名),这个一维数组有三个元素,分别为a[0][0]、a[0][1]、a[0][2]。

a[1]是第二个一维数组的数组名(同样的一定要将a[1]看做一维数组的数组名),这个一维数组有三个元素,分别为a[1][0]、a[1][1]、a[1][2]。

这样将二维数组拆成多个一维数组来理解,就可以将二维数组问题转化为一维数组问题,上面所讨论的关于一维数组的数组名、首元素、数组地址的结论均可应用到二维数组上来。

首先,同一维数组一样,a,&a,a[0]和&a[0]在数值上是完全相等的,但含义不同。

a是二维数组的数组名,是一个指针常量,只能做右值,不能做左值,做右值时表示数组首元素的首地址。这里数组的首元素是谁?没错是a[0],不用怀疑,只不过这个元素有点特殊,这个元素本身又是一个一维数组罢了。因此a和&a[0]是完全等价的。

&a是整个二维数组的地址。

现在来讨论指针指向二维数组数组名、数组元素的问题:

1.指针指向二维数组的数组名:二维数组的数组名a做右值时相当于首元素a[0]的首地址(也就是数组名字为a[0]的数组的地址),而a[0]是一个一维数组的数组名,其本质为指向一维数组的指针,因此要指向二维数组的数组名,实质是需要定义一个指向一维数组的指针:int (*p1)[3] = a;

上述定义也就相当于int (*p1)[3] =&a[0].这里p1是一个指向含三个int类型元素的一维数组,而a[0]正好是一个含三个int型元素的一维数组的数组名,对它取地址就表示含有三个int型元素的数组的地址,正好和二维数组名a的含义相同。

2.指针指向二维数组的各个元素的数组名(二维数组当做一维数组看待时,其各元素为一维数组)

这里的各个元素指的是把二维数组当成一维数组看待时的各个元素,此时a有两个元素,a[0]和a[1],分别为两个一维数组。a[0]和a[1]作为两个一维数组的数组名,表示的是一维数组的首元素的首地址。对于一维数组a[0],其首元素为a[0][0],是一个int型的变量,要想让指针指向其数组名,必须定义一个int型指针:int *p2 = a[0];

上述定义也就相当于int *p2 = &a[0][0].这里p2是一个指向int型变量的指针,而而a[0]是一个一维数组的数组名,表示的是一维数组的首元素a[0][0](一个int型变量)的地址,可见p2和a[0]以及&a[0][0]的类型是匹配的。

同理要定义一个指针指向二维数组的第二个元素(当做一维数组看待时)a[1],只需定义一个int型指针指向它即可:

int * p3 = a[1];也即int *p3 = &a[1][0].

3.指针指向二维数组

这里的指向二维数组是指定义一个指针让其指向整个二维数组。

注意和上面讲的指针指向二维数组的数组名相区别,二维数组的数组名表征的是二维数组首元素的地址,也就是其作为一维数组的各个元素中的第一个元素(是一个一维数组)的地址,说白了就是定义一个指向一维数组的指针。

所以

要定义一个指向二维数组的指针:int(*p4)[2][3] = &a;

这里p4是一个执向二维数组的指针,指向一个什么样的二维数组呢?指向一个第一位大小为2,第二维大小为3的二维数组,也就是指向一个含有两个元素,每一个元素都是一个含3个有int型元素的数组的数组。

好像有点绕,后面我再改改,精炼一下。。。。

猜你喜欢

转载自blog.csdn.net/weixin_39330853/article/details/81772971