一、从内存角度理解数组
从内存角度来讲:数组变量就是一次分配多个变量,而且这多个变量在内存中存储单元是依次相连的。
我们分开定义多个变量(int a,b,c,d),和我们一次定义一个数组(int a[4])。这两种方法的相同点都是定义了4个int变量,且这4个变量都是独立单个使用的。不同点时是单独定义时a、b、c、d在内存中的地址不一定连续,但定义成数组后,数组中的4个元素地址肯定是依次连续的。
数组中多个变量虽然必须单独访问,但因为他们的地址彼此相连,因此很适合用指针来操作,因此数组和指针天生就纠缠在一起。
#include <stdio.h>
{
int a,b,c,d; //分开独立定义4个int变量
int a[4]; //一次定义一个数组,包含4个int类型
//这两种定义的变量都只能一个一个单个使用、访问
}
二、从编译器角度理解数组
从编译器角度来讲:数组变量也是变量和普通变量和指针变量没有本质不同。
搞清楚变量、变量名、变量类型三个概念的具体含义
变量的本质就是地址,这个地址在编译器中决定具体数值,具体数值和变量名绑定,变量类型觉得地址的延续长度。int a; char a; 地址的默认单位是字节,变量名a就是一个点,变量类型决定由这个点向上连续的几个字节存储空间。
三、对数组几个关键符号(a a[0] &a &a[0])的理解
这4个符号搞清楚了,数组相关的很多问题就清楚了。关键是搞清楚结合左值右值来思考每个符号分别做左值和右值的不同含义。
1. a就是数组名。
a做左值时含义是整个数组的所有空间int a(10) (10x4=40字节),又c语言规定数组操作时,变量要独立单个操作,不能整体操作数组,所以a不能做左值。注意数值初始化的式子和赋值表达式有所不同。
a做右值表示数组的首元素的地址(也就是首地址)a做右值等同于&a[0]
#include <stdio.h>
{
int a[10]={1,3,4,0} //不是a做左值而是数组初始化
a[0]=4;
a[1]=44;
a={1,4,5,32}; //错误的,数组元素必须单个访问,不能整个数组访问。
}
2. a[0]表示数组的首元素也就是第0个元素。
a[0]做左值时表示数组第0个元素所对应的内存空间(连续4字节)
做右值时表示数组第0个元素的值
3. &a就是数组 名a取地址 ,字面意思来看就是数组的地址。
&a不能做左值,因为&a是一个常量不能赋值所以不能做左值。
因为数组是编译器在我们内存中自动分配的,在每次运行时,编译器都会分配一块内存给数组,只要完成分配,这个数组地址就定好了,到运行终止都无法改变。我们只能通过&a来获得数组的地址,但不能修改它。
&a做右值时表示整个数组的首地址
&a与a做左值时的区别:
这两个在数值上是相等的,但是意义是不相同的。意义不相同导致两个在参与运算时结果不同。
4. &a[0]表示数组的第0个元素的首地址([ ]的优先级高于&)。
做左值时表示数组首元素对应的内存空间。
做右值时表示数组首元素的内存空间。做右值时&a[0]=a