buzhidaozenmeshuo
- 前因
- 经过
- 后果
- 说明
- 畅想
前因
在《C程序设计》中看到这样一段代码讲解2维数组,看起来像是能被整理总结的东西。
#include<stdio.h>
int main()
{
int a[3][4] = { 1,3,5,7,9,11,13,15,17,19,21,23 };
printf("%d,%d\n", a, *a); //0行起始地址和0行0列元素地址
printf("%d,%d\n", a[0], *(a + 0)); //0行0列元素地址
printf("%d,%d\n", &a[0], &a[0][0]); //0行起始地址和0行0列元素地址
printf("%d,%d\n", a[1], a + 1); //1行0列元素地址和一行起始地址
printf("%d,%d\n", &a[1][0],*(a+1)+0); //1行0列元素地址
printf("%d,%d\n",a[2],*(a+2)); //2行0列元素地址
printf("%d,%d\n",&a[2],a+2); //2行起始地址
printf("%d,%d\n",a[1][0],*(*(a+1)+0)); //1行0列元素的值
printf("%d,%d\n",*a[2],*(*(a+2)+0)); //2行0列元素的值
return 0;
}
经过
当我们看到题设概念,我们希望尽可能贴近我们的常识。这样我们就可以不用记忆或者少记忆来理解这个知识。定义一个int 类型的数组,就是得到一段空间,其最小内存单元为int。称之为数据项(数据结构中不可分割的最小单位)。我定义了一个数组a,它就是这段总空间的名字。它是由若干int类型的基本数据项组成。由int一层抽象(扩大)为列,二层抽象为行,三层抽象为页等等(不是我不想继续,是后续没有了)我们从a开始缩小范围。所谓缩小,即是增加精确度。第一个方法是a[0](这种方法合乎常识,就不解释它了),它提高了精确度。它称之为0行0列元素地址。它从二维变成了一维。我再精确一下,变成了a[0][0],发现它已经精确到了数据项,精确到了极致。我能够得出它的值了。所以a[0][0]称作0行0列元素的值。这样解释很合理。可是还有指针符和取地址符。经过观察可得出结论
后果
*提高精确度
&降低精确度
我们看
a=&a[0]=&(*(&a[0]))=&(&( * ( * (&a[0]))))
a[0]=*(a + 0)=&a[0][0]= *(a+0)+0=&( * ( * (&a[0])))
a[0][0]= *( * (a+0)+0 )= *(&a[0][0])= * ( * (&a[0]))= * * a= * (&( * (&( * (&( *(&a[0][0])))))))(吓人吗?)
注解:1.不可两次连续抽象(&&),但可以两次精确(**)(标红的第二个式子报错)
2.抽象到整体的机会只有一次(标红的第一个式子报错)
说明
我很高兴能退出这个结论,这样再高的纬度又奈我何?至于这两个注解是我根据实验数据总结的。若有更好的总结,欢迎留言。
畅想
有人可能要问笔者为何起始地址不画在起始位置标个箭头而是直接画在图中。是不是错了,是不是不准确?其实不然。我们是通过什么来记忆人像呢?是通过头嘛,头在一定程度上能代替整体,不存在通过角来辨识别人的吧。比如a[0],计算机说我找到了,把它的头像呈现给您。至于他的大小你看它是啥,a[3][4]那就是4,a[3][4][5]那就是4*5=20;您给的精确度就这么大,我也只能帮您到这里了。抱着精确的目的,而给的这两个注解是因为计算机希望找到最精确的点。而不是一个大概的位置。合情合理。