数组名a作为左值和右值的区别
简单而言,出现在赋值符“=”右边的就是右值,出现在赋值符“=”左边的就是左值。
比如,x=y。
左值:在这个上下文环境中,编译器认为x的含义是x所代表的地址。这个地址只有编译器知道,在编译的时候确定,编译器在一个特定的区域保存这个地址,我们完全不必考虑这个地址保存在哪里。
右值:在这个上下文环境中,编译器任务y的含义是y所代表的地址里面的内容。这个内容是什么,只有到运行时才知道。
C语言引入一个术语——“可修改的左值”。意思就是,出现在赋值符左边的符号所代表的地址上的内容一定是可以被修改的。换句话说,就是我们只能给非只读变量赋值。
既然已经明白左值和右值的区别,那么下面就讨论一下数组作为左值和右值的情况。
当a作为右值的时候代表什么意思呢?很多书认为是数组的首地址,其实这是非常错误的。a作为右值时其意义与&a[0]是一样的,代表的是数组首元素的首地址,而不是数组的首地址(用在表达式sizof(a)中时,a表示的是数组名,此时a并没有被用作右值),这是两码事。但是注意,这仅仅是代表,并没有一个地方(这只是简单地这么认为,其具体实现细节不做过多讨论)来存储这个地址,也就是说,编译器并没有为数组a分配一块内存来存储其地址,这一点就与指针有很大的差别。
a不能作为左值!这个错误几乎每一个学生都犯过。编译器会认为数组名作为左值代表的意思是a的首元素的首地址,但是这个地址开始的一块内存是一个总体,我们只能访问数组的某个元素,而无法把数组当做一个总体进行访问。所以我们可以把a[i]当左值,而无法把a当左值。其实我们完全可以把a当做一个普通的变量来看,只不过这个变量内部分为很多小块,只能通过分别访问这些小块来达到访问整个变量a的目的。