数组名的讨论
1、int a=10;
在栈申请一块空间,四个字节,这个内存里面放的是10的二进制码,在8086架构里,按小端方式存储。
-
&a,得到的是头一个字节的地址(首地址),对&a+1,指向下一个这种类型的空间首地址。
-
*a,解开的是这个空间的内容,是个int类型。
-
a,是这块内存的标识符,也就是名字,不在内存中显示,由编译器识别,然后处理。
因为类型是int类型,所以a指的是四个字节的范围。
对a进行赋值,取出这个int类型的地址的内容(四个字节的内容),往里面赋值。
2、int a[3]={1,2,3};
在栈申请一块空间,类型:3个元素是int型数据组成,总共12个字节,低地址放1。
-
a,指的是这块内存的标识符,这块内存的类型是数组类型。12个字节的空间。
-
&a,得到的是首地址,对&a加一,指向下一个这种类型的空间首地址。
-
*a,解开的是空间的首元素的内容。首元素是个int类型的数据;
但是想取到a[3]数组中的第三个值的地址咋办嘞?
可以这样做——
(int *)(&a)+2
把这个地址对应的东西的类型,转化成int 类型。
可是有点复杂,所以编译器提供了一种操作,往下看:
因为我们不用对a复制,数组不能直接a=b,这种操作,所以,这个a就可以另作他用,可以当作首元素的地址指针。
这样我们对这个a[3]的第三个值取地址,直接a+2;取值的话直接*(a+2),但是还是有些复杂,C语言是希望小而简,所以想要得到这个3的值,还可以a[2],直接不用取地址,a[2]表示的就是*(a+2),就是3。
3、int a[2][3]={1,2,3,4,5,6};
在栈中申请一块空间,这块空间的类型是两个数组元素的数组类型,这两个元素,每个元素是3个int元素的数组,一块内存是数组类型,每个元素的类型是数组,这个数组的每个元素是int。
-
a 是这个空间的名字,是有两个元素的数组的名字。类型:两个元素是int [3](数组)型数据组成。而里面的数组的类型:3个int型数据组成;
-
&a,得到的是首地址,但是因为a代表的是这个整个空间,所以,对&a加一,指向下一个这种类型的空间首地址。
-
a 还可以表示的是首元素的地址指针,上面说了的。
-
*a,得到的是首元素的内容,首元素是一个数组,是个有三个int型数据组成的空间,就是这小数组的标识符了也就是名字了。
还是因为我们不能对整个数组进行赋值,所以*a,这里的概念也要转变一下,把他当作这个数组首元素的地址指针,*a,代表的就是头一个小数组的首地址,第二个小数组的首地址怎么表示嘞?
没错就是*a+1;不知道你有没有抢答,a[0]a[1],同样可以表示。
然后再往下推 *(*a),*(*a+1),分别是头一个小数组和第二个小数组的首元素,*(*a)+1,*(*a+1)+1,分别是第二个元素。a[0][1],a[1][1],同样可以表示。
思考题:
*(&a)表示的是什么呢?
&(*a)表示的又是什么呢?
*(&a)+1表示的是什么呢?
&(*a)+1表示的又是什么呢?