背景
今天遇到有朋友询问这个问题,发现自己已经忘记了,粗浅的复习了下,描述的了一下自己的理解,如有错误还望斧正,希望不要误人子弟了
普通二维数组与行指针:
普通二维数组定义:int a[10][20]
内存本质:a本质上是一个指针,指向空间中的一个位置,在这个位置上,a[0][0]到a[9][19]连续排列。
在编译过程中:a[5][10]都是要转化为类似*(*(a+5size(10*int))+10*size(int))这样的形式然后计算出地址
**对于运算符的解释**:假设p为地址,则*p表示p所在地址存的数据。在c语言中如a[5][10]可以用*(*(a+5)+10)来表示,可见这时,size里面的值是不用我们写出来的,这说明在开始编译的时候,这几个值就决定了。
重点:可以用行指针 int (*p)(10)指向上述普通二维数组的a而不会出错
指针数组与二重指针
指针数组定义:int* (p[10]) 等价于 int p[10] 附:因为会先和左边的int结合,所以括号不加也可以
内存本质:p本质上是一个指向指针的指针,它指向了10个排列在一起的int类型的指针。
使用说明:这个时候p[5]表示某个指针,可以手动使得这个p[5]指向如list[20]
即:
int (p[10]);
int list[20];
p[5]=list;
此时,p[5][10]的值就是list[10]的值。
编译过程中:与上面普通二维数组不同的是,a[5][10]转化为类似 *(*(a+5*size(int*))+size(int))然后计算出地址
同样,在c语言中可以用*(*(a+5)+10)来表示。这时候与上面写出来(不带size)的表示一样,实际本质是不一样的。
*(*(a+5*size(10*int))+10*size(int)) 上面的式子是
*(*(a+5*size(int*))+size(int)) 此处的式子是
可清楚的看到不同的地方,一个是10*int一个是int*,这就是两种指针不同的地方。因为行指针指向的是每列数据都在行上连续排列,二重指针指向的却是一串连续的存储指针的空间。
重点:可以用二重指针 int**a指向上述指针数组的p而不会出错。