前言
- 本文是作者查阅资料后根据代码演练,得出的结论。结论仅用于知识点的关联总结。
- 本文的
&
统一称为取地址操作,*
统一称为解引用。关于解引用,可参考:解引用的理解 - 本文不再介绍二维数组与一维数组的关系
1. 一个二维素组在内存中的结构
int array[][3] = {{1,2,3},{4,5,6}};
2. 数组名 & * 三者的组合用法
会惊奇的发下,以下的表达式,都输出了同一个地址值
int main() {
int array[][3] = {{1,2,3},{4,5,6}};
printf("array 地址 : %p \n", array);
printf("*array 地址 :%p \n", *array);
printf("array[0] 地址 : %p \n", array[0]);
printf("&array[0] 地址 : %p \n", &array[0]);
printf("&array 地址 : %p \n", &array);
return 0;
}
2.1 array
二维数组名array
,%p
代表的是数组首元素的首地址,即a[0]
的地址
2.2 array[0]
由2.1可以推论,array[0]
为二维数组的首元素,%p
代表二维数组的首元素的(一维数组)中的首元素的地址,即array[0][0]
的地址
2.3 &array
对二维数组进行取地址操作 %p
代表 array
的地址
2.4 *array
是 array[0]
的语法糖,根据:见视频 04:54,结论见2.2
2.5 &array[0]
由2.2可以推论,array[0]
为二维数组的首元素,取地址操作见2.6的图
PS:&
取地址操作,%p
即为地址值
2.6 描述成图
3. 代码证明
按层*
进行运算, 即解引用,图片上就是按层缩进,直到找到值1。
如 &array 就是需要四次解引用才能找到值1
int main() {
int array[][3] = {{1,2,3},{4,5,6}};
printf("array 地址 : %p | 解引用: 略 \n", array);
printf("*array 地址 :%p | 解引用: *(*array) : %d \n", *array, *(*array));
printf("array[0] 地址 : %p | 解引用: *(array[0]) : %d \n", array[0], *(array[0]));
printf("&array[0] 地址 : %p | 解引用: *(&array[0]): %d 地址: %p | 解引用 : *(*(&array[0])) : %d \n", &array[0], *(&array[0]), *(&array[0]), *(*(&array[0])));
printf("&array 地址 : %p | 解引用: *(&array) : %d 地址: %p | 解引用 : *(*(&array)) : %d 地址 : %p | 解引用 *(*(*(&array[0]))) : %d \n",
&array, *(&array), *(&array), *(*(&array)), *(*(&array)), *(*(*(&array))));
return 0;
}
后记
对于数组,C语言提供了方便,也可以说不严格,比如如下函数。
char name[51];
scanf(%s, &name);
// scanf(%s,name); 跟上面的效果是等价的
作者也只是在大学简单得学了C语言,现在回过头来看数组名的解释对于初学者很不友好,作者认为没有必要过分纠结这个事情,探索只是兴趣使然,实际使用的话仅记住结论即可。