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 这个数,和我们想的一样。

  

 

01-15 03:41