浅挖二维数组指针

从一维数组开始

假设有数组int a[]={1,2,3}, 我们可是通过一系列的方式访问它
定义:int *p; p=a;
则p指向了a。此时我们姑且认为a与p等价。

需求 使用 a 使用 p
访问数组第一个元素 a[0] *p
同上 *a p[0]
访问数组第二个元素 a[1] *(p+1)
同上 *(a+1) p[1]

将上述数组转化为图,即下图所示(这里1是指int的单位大小):
在这里插入图片描述
所以对于使用指针来讲,*(数组元素地址) 即可访问数组对应元素。
可以清晰的看出a 是数组a[] 的地址; 也是数组a[] 第一个元素的地址。所以该地址有双重的身份,这双重身份可以被计算机解读,取决于数组在c语言中的特殊结构设定。两个身份并不矛盾,可以理解为同一身份。
为了更清楚的理解,我们写了一个小实例,定义了一个数组a,用指针 p 来指向 a 运行结果如下:

int *p=a;		//runing...结果:
  &a:6487376     a:6487376       *a:1
  &p:6487576     p:6487376       *p:1

&a 取到的是数组a 的数组地址(第一重身份), a 是数组第一个元素地址(第二重身份),均为:6487376,两个身份一致,至于不同的解析取决于 c 的数组结构定义。
而指针 p 来讲,p 有自己的地址(并且有自己的 大小 和 总线 有关),p指向的是(!!可能是!!)数组的地址(不排除是第一个元素的地址的可能),(当然这也不重要,就看官方是怎么诠释而已,不影响理解)。

二维数组指针 :type (* q )[列数]

故名思意,该形式首先是个数组,但是数组的每个元素都是指针。
设有数组: int B[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12};
  1.我们可以将它理解为两个嵌套的数组,首先第一数组即是B[4], B[4]的每一个元素都是一个长度为[3]的数组首地址。
  2.首先探讨B[4],可以将B[4] 理解为一维数组,类似上面所述。所以B 是该数组的B[4] 的地址; 也是数组B[4] 第一个元素的地址,该元素可以通过两种书写方式取得:B[0]、*B 。

1 2 3 4

  3.在1.中我们假设了,B[4]的每一个元素都是嵌套数组中的子数组首地址,设第一个子数组为b1[3], 一维数组,首地址(第一个元素地址)为b1, 那么2.中我们取得的 B[0] (或*B),即是b1。(见下图,仅展示前B[3])
  4. 欲取得b1中的元素(设b1中第一个元素),我们可以通过,b1[0]、*b1, 两种写法。同理代入B,完整的写法可以推出:B[0][0] 、*(B[0])、(*B)[0] 、**B。
  5. 经过验证,4.中所述写法完全可以编译运行,完美取得B[4][3] 中的第一个元素。所以基本验证了我们的假设:B矩阵属于一个嵌套数组。B是矩阵首地址、是矩阵第一个子数组首地址,但是矩阵首地址(矩阵第一个元素地址)中存放的是 矩阵第一个子数组首地址(子数组第一个元素地址),只有矩阵的子数组中,才存放着具体的元素。
在这里插入图片描述
  6. 俄罗斯套娃。在B是[4][3], 矩阵的前提下,设B的地址(&B)为:6487424、B存放的地址是:6487424、取得B存放的地址中的元素(B)我们发现竟然是:6487424, 但是当在一次取B地址中的元素(**B)我们发现却是 1 。
即是:&B == B ,B == *B , 但是 *(*B) != B 。一个内存位置上 存放着 该位置的地址
首先从上一章节一维数组中,我们知道 &B == B 是对数组结构的特殊诠释。但 B == *B ,就可能是 c 语言中 ,对二维数组的不同的额外特殊诠释。只有当对地址多次取值,才能真正取得地址上的元素 1 。
  7. 我们甚至可以将二维数组直接利用指针的方式转化为一维数组,p=&B[0][0]; 语句相当简单,就是直接指向矩阵的第一个元素。
  8. 我们还可以讲:指向二维数组的指针的定义方式,是定义一个指向第一层嵌套数组(在例子中即是指向 B[4])的指针。数组很重要的属性是类型,数组类型决定了为每个元素分配内存的大小,第一层嵌套数组而言,矩阵B[4][3] 的列向量就显得尤为重要,因为列数表明第一层嵌套数组每个元素的大小(sizeof( type X ) * 列数)。
9. 那么类比一维数组指针的定义:type * p = a;
10.  推出二维数组指针的定义为:type (*q)[m] = B, 其中type B[][m] ;

&B is:6487424
 B is:6487424
 *B is
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值