1. 左值和右值
简单的定义来说,能够放在赋值等号左边的就是左值,反之则是右值(所有表达式不是左值就是右值,左右值不存在交集)——但是这个解释实在有点鸡肋。下面对定义结合例子做些补充。
- 右值:在内存中不占有内存的表达式
- 左值:在内存中占有一定内存位置的表达式
1 int i; 2 i = 2; //合法 3 2 = i; //非法
例子合法性很好理解——可以在结合左右值的定义。
1 #include<iostream> 2 int main() 3 { 4 int t; 5 int* q = &(t + 1);//非法,t+1在内存中没有位置 6 7 int arr[] = { 1,2,3 }; 8 int* i = arr; //合法 9 std::cout << arr << std::endl; // 006FF808 10 arr = &t; // 非法 11 *(arr) = 10;//合法 12 }
在这里,我们需要理解下第八行,arr 作为右值—— 注意 arr 是内存地址,是一个地址,不同于第一个例子中的 i 。在第九行可以看到打印的 arr 代表的地址内容,第十行也就必定是错误的(是右值就不可能作为左值)。
而第11行,arr 貌似变成了左值——也就是左值和右值在一定程度上是可以转换的。其中扮演关键角色的就是 * 解引用。既然是左值,按照我们前面说的,那应该在内存中存在一处分配的内存位置,*arr 解引用之后的确是存了 1 这个数,和我们想的一样。