大家在学习数组指针和二维数组的时候,有没有觉得*(*(p+i)+j)==a[i][j] 这个等式有点难以理解?所以今天目的核心就是通过对这个式子的推导,更好更深刻地理解c++对数组指针和二维数组的理解。
数组指针是一个指针!是一个一维数组形式的指针,也是通过首地址去传递的!指针数组则是一个数组!里面元素是指针。int (*p)[4]定义的意思就是一个指向4×4==16
字节内存地址的指针!
C中的二维数组在存储上是一维线性的!同时C语言规定,数组名在值上等于数组首元素地址,它是一个指向该数组首元素的指针!
int a[3][4]=0
{
a[1],
a[2],
a[3]
};
其中
a[1]={1,2,3,4},
a[2]={5,6,7,8},
a[3]={9,10,11,12},
别怀疑,C语言就是这样定义和理解二维数组的。我把二维数组a的定义故意写成这样就是因为C语言就是这么去理解的!要从C语言(机器)的角度去理解代码!
首先:
在一维数组中有,最重要的就是数组名等于首元素地址这个C语言规定,
即a==&a[0]
,a+i==&a[0]+i==&a[i]
.(这个应该好理解,a是指向数a[i]这个一维数组的指针,首先存放的是a[i]数组首元素a[0]的地址,则对该指针进行加减,
由C++定义指针加减需要根据其定义的指针类型确定偏移量!!!
例如定义的一维数组a[i]是int类型,单个元素内存是4字节则a+1就会跳到下一个元素首字节的地址,即指针地址跳跃4个b。)则二维数组中一样,
a==&a[0]; a+i==&a[0]+i==&a[i]
int (*p)[4];
则有p=a;
**注意关于数组指针的定义要记牢,必须和二维数组的列数相等!否则指针指向内存大小和所指的内容内存大小对上不一一对应的话,C++语言是无法按照他的存储逻辑进行运算的!以下公式的推断严格按照C++的角度去理解推论的!
①p==&a[0] a[0]==&a[0][0]
则p==&&a[0][0](数组名等于首元素地址!数组名是a,首元素地址是&a[0], 数组名是a[0],首元素地址是&a[0]0],嵌套理解该定义!)
② p+i==&a[0]+i==&a[i]==&&a[i][0]
( p是指向a这个二维数组的数组指针,基于上述开头所说,我们定义的是一个指向16字节内存的数组指针。所以它的指针p加减运算跳跃的内存是该二维数组的一行内所有列元素内存,即跳跃了一整行的元素内存,可以理解为矩阵行变换、行运算。例如p+1,p的地址若是0x000000,则p+1为0x000010,变换了4b×4=16b的内存,。对于int类型的二维数组,int类型数组单个最小元素占用4字节,所以变换一行,一行有4元素,4b×4=16b)
③*(p+i)== a[i]=&a[i][0
]
④*(p+i)+j==a[i]+j==&a[i][0]+j==&a[i][j]
(已经代表着可以在二维矩阵的具体元素的地址上进行加减了)
⑤*(*(p+i)+j)==a[i][j]
(顺利推导,二维数组元素的值可以用*(*(p+i)+j)
表示,也可以用a[i][j]表示,还可以用*(a[i]+j)
表示,也等于*(p[i])+j)
表示。从数学角度理解,p==a就好。)