二维数组的原理与指针运算的原理

上次梳理了一维数组的与指针的原理以及它们的关系,我们再来看看二维数组。

当我们定义一个二维数组时,实际上占用的是内存中连续的线性空间。

倘若我们定义整形的二维数组:int b[2][3],实际上它在内存中占用连续6个整形元素的空间。而且是3个元素一组,形成2组一维数组。

这句话的意思是,二维数组b[2][3]可以看作包含两个元素的一维数组,而每个元素又恰好包含3个整形的元素,恰好也是一维数组。

根据这个原理,我们可以 将二维数组看作是嵌套的一维数组,即分作外层一维数组与内层一维数组。

同理,既然是一维数组,就有内嵌的特殊指针。

外层的一维数组我们可以看作是b[2],它具有特殊的指针b,指针地址是一维数组b首个元素b[0]的地址,即&b[0],指针b存取着数组首个元素b[0]的地址,所以b == &b[0];

既然存在指针,当然可以进行指针运算,同一维数组,我们对指针b进行指针运算也是对指针b存取的地址进行更改,只是…指针b每+1,地址加多少位呢?我们定义的数组数据类型为整形,可我们这个“特殊”的外层一维数组每一元素占用地址不是一整形地址,而是3整形地址。即3*4 = 12 字节。

所以,当我们对b进行指针运算时,得出的地址是下一个包含3个整形元素的元素的地址,即外层一维数组下一个元素的地址。

说完了外层的一维数组,我们再来看内层的一维数组。

内层的一维数组与普通一维数组无异,均由存取着数组首元素地址的指针进行服务,这个指针没有名字,它的地址也是数组首元素的地址,若是第一个内层一维数组,指针的地址即&b[0][0],若是第二个内层一维数组,指针的地址是&b[1][0]。

开始我们说过,地址的表示与划分是从内存中首个元素头部开始的, 在我们定义的整形数据类型这里,开始处就是这段连续的线性空间首个整形元素的地址。然后这就解释了为什么外层的一维数组指针的地址与内层第一个一维数组的指针的起始地址是相同的。其实他们各自的指针存取的地址都是同一块内存的地址。

我们对内存的一维数组的指针进行指针运算时,每次运算都是对所存地址的更改,因为是整形元素,所以每单位运算更改是四个字节,对内层指针的运算结束之后再进行解引用,就可以精确的拿到整形元素所存取的数据。

以上是外层数组和内层数组各自指针运算的原理,我们如何控制指针呢?

其实玄机就在于指针他存的就是地址!!

譬如,我们想拿外层数组第二个元素内的第三个数组元素存取的值,即b[1][2]。

当我们对外层一维数组进行指针运算时,我们可以写作(b + 1)(不要忘记前面说的,外层一维数组的指针有名字的,内层一维数组的指针没有!),它表示指针b中存取的地址突然增加了12字节(如果没明白,往上看),好,本来指针b存取的是外层数组元素的首地址现在了突然增加了12字节,正好是外层一维数组第二个元素的起始处!OK,我们的b指针进行了指针运算,现在我们的指针b拿到了外层一维数组第二个元素的地址。

可你别忘了,外层数组第二个元素也是一个具有三个整形元素的一维数组啊!外层数组的第二个元素的地址正是内层一维数组内嵌指针的的地址,也是指针存取的地址。 所以我们上面进行的操作实则是拿到了第二个内层一维数组指针的地址!

那如何将控制权从外层数组的指针转移到内层数组的指针呢?
就是对拿到的数据进行解引用。

不要忘了,因为内层指针也是具有地址的,我们刚刚对外层指针b+1运算之后拿到的地址就是外层第二个元素的地址就是其内层一维数组的首个元素的地址就是其指针的地址就是其指针保存的地址。 当我们对已运算指针(b+1)获取的数据(这个数据就是外层数组第二个元素的地址,就是其内层一维数组指针的地址~)进行解引用, 就是找到运算之后外层指针b存放的地址对应的元素的内容,取得的仍然是一个地址(因为第二个外层元素的地址就是其内层一维数组指针的地址,解引用是按地址寻对应上地址的元素的数据,那么寻址就会找到内层指针的数据,而内层指针存取的地址又是与自身地址相同,所以取得的还是地址~),这个地址就是第二个内层一维数组的指针存取的地址(同样的此指针存取的地址与其指针本身的地址相同),

结果就是 *(b+1) 之后取得的不是数据,而是一个指针存取的地址, 所以,我们成功获取了内层一维数组指针的存取的地址。

这又来到了内层一维数组的指针运算操作,此时再对指针进行指针运算,就是对解引用之后的 (b+1)(解引用之后是个地址~)进行运算: (*(b+1)+2) 得到我们想取得的元素的地址,此时对指针再次解引用, 按地址寻数据:*(*(b+1)+2) 就可取得指针所存地址对应元素的元素的内容了,这时就是一个数据了。

我们发现,二维数组指针操作的过程中,外层指针存取的地址对应的元素不是数据,而是地址(是一个指针)。即对指针的地址解引用一次仍然得到一个指针的地址(仍需第二次解引用),这种指针指向指针的的特点,称为二级指针。

实际上,一维数组是用一级指针进行操作的,而二维数组是用二级指针来进行数据的操作的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章