多维数组与指针 精析

来源:互联网 发布:结爱犀燃烛照结局知乎 编辑:程序博客网 时间:2024/04/29 20:38


(2009-12-07 11:01:53)
转载
标签:

杂谈

 

可以认为 C语言中只有一维数组,没有真正的二维数组。如二维数组a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}},

可以认为是一个 一维数组 :a[3]={ a[0], a[1], a[2] }其中 a[0],a[1],a[2]又是三个有四个元素的一维数组,

   即 a[0]={1,3,5,7 },a[1]={9,11,13,15 },a[2]={ 17,19,21,23 } 。

   现在大家考虑下面一个问题, 一维数a[6]={1,2,3,4,5,6} 中, a 表示数组首地址,即 a[0] 地址, a+1 为 a[1] 地址,也即 a+1 指向a[1], *(a+1) 是元素 a[1] 的值。

   对 二维数组a[3][4] , a 是 数组首地址,但 a+1 不是 a[0][1] 的地址,而是与第 2行,第 1 个元素 a[1][0] 的地址相等,也就是说 a+1 指向了下一行,若把 二维数组a[3][4] 当作是由三个一维数组组成的数组(这三个一维数组的数组名分别为 a[0], a[1],a[2] ),则 a+1 指向了一维数组 a[1] 。而对 一维数组来说,数组名 a[0] 是元素 a[0][0] 的地址,所以a[0]+1 是 a[0][1] 的地址,即 a+1 与 a[0]+1 都是地址,但指向的元素不一样, a+1指向第二行的一维数组,而 a[0]+1 指向具体的数组元素 a[0][1] 。

  综合上述,总结如下:

   二维数组a[3][4] , 可以看作是有三个以一维数组为元素的数组,这三个一维数组的数组名分别是 a[0],a[1] 和 a[2] 。

    数组名 a,为数组首地址,即其第一个元素(一维数组)的地址,指向第一个元素(一维数组), a+1 指向第二个元素(第二个一维数组), a+2指向 a[2]

又由于 a[0], a[1] 和a[2] 为一 维数组,故它们也是数组的首地址。 a[0] 是第一个 一 维数组的数组名,即它是第 1 行第 1 个元素a[0][0] 的地址,a[0]+1

指向 a[0][1], *(a[0]+1) 是 a[0][1] 的值。 也即,不管 二维数组还是一维数组,它们的数组名都是数组的首地址,都指向数组的第一个元素,只不过,对二维数组

来说,数组名指向的是一个 一维数组(地址),而不是一具体数值;而对 一维数组来说,数组名指向的是一 具体数值,而不是一 个地址。应特别注意的是 a,a[0]

都是地址,且数值是相同的,但 a 指向一维数组,而 a[0] 指向一个整型数值,它们的类型是不同的,所以 a+1 与 a[0]+1的含义不但不同,数值也是不一样的。

  1. 多维数组的地址

   通过上面的讨论,我们直接得到以下结论:

   对a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}

 

 

 

a[0]

a[0]+1

 

 

a,a+0

1

3

5

7

a+1

9

11

13

15

a+2

17

19

21

23

 

   a是 二维数组的名字,是二维数组的首地址,即第0行的首地址

   a+1是数组 a 第 1 行首地址

   a[0],a[1],a[2]是二维数组中三个一维数组的名字(地址),是第 0 行第1 个 ,第1 行第 1 个,第 2 行第 1 个元素的首地址。

   a[i]+j是第 ij列的地址

   *(a[i]+j)是该地址存储的值,即 a[i][j]

   a+1 以行为单位移动,而 a[I]+1在同一行以列(一个元素)为单位移动,所以 a+I 是行指针, a[I] 是列指针,a+1是个指针,指向第一行的一维数组,那么

*(a+1) 就是个一维数组(的数组名),而第一行的一维数组的数组名是 a[1], 所以 *(a+1)=a[1], 也即 *(a+1)指向了数组元素 a[1][0] ,变成了一个列指针,可

见对行指针进行 * 运算,就变成了列指针

  同理 a[1] 是数组名,&a[1] 表示指向该数组的一个指针,即 a+1,可见对列指针(数组名)取地址,就得到一个行指针,也即指向一个一维数组的指针。

   大家思考一下 *(a+1)+1 和*(*(a+1)+1) 的含义  /*(1)指向第一行第一列的指,(2)代表第一行

                                                /*第一列指针所指的元素,前题都是从0行0列开始

   大家再思考一下&a[1][0] 和&(&a[1][0]) 的含义/*(1)指第一行的列指针,(2)变成指向行的指针

   可以得到一个结论,对行指针进行一次* 运算,它将变成列指针,进行两次 * 运算,它将变成一个数值

   同理,对数组元素进行一次& 运算,它得到一个列指针,进行两次 &运算,将得到一个行指针

  现在再来看以下式子的含义:

   a, *a,**a

   a+1,&a[1]

   a[1],*(a+1)

   a[1]+2, *(a+1)+2,&a[1][2]

   *(a[1]+2),*(*(a+1)+2), a[1][2]

  大家思考以下,下列式子值是否相同,含义是否也相同

   a, *a, a[0],&a[0][0]

   a+1, *(a+1),a[1], *(a[1])

   *(a[I]+j),*(*(a+I)+j), a[i][j]

 

 总结: 1. 二维数组名,指向一维数组的指针,行指针 三者等价

2.一维数组名,指向具体元素的指针,列指针 三者等价

3.行指针加 * ,变成列指针,行指针加 ** ,变成元素

4.列指针加 * ,变成列元素,列指针加 & , 变成行指针

也即行指针、列指针、元素通过 [* , &]两个运算符号,可以相互转化


原创粉丝点击