前言
- 本文是作者查阅资料后根据代码演练,得出的结论。结论仅用于知识点的关联总结。
- 本文的
&统一称为取地址操作,*统一称为解引用。关于解引用,可参考:解引用的理解 - 本文不再介绍二维数组与一维数组的关系
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语言,现在回过头来看数组名的解释对于初学者很不友好,作者认为没有必要过分纠结这个事情,探索只是兴趣使然,实际使用的话仅记住结论即可。

3650

被折叠的 条评论
为什么被折叠?



