左值位于赋值运算符的左边,它在内存中必须有实体。
右值位于赋值运算符的右边,它可以存在于内存或CPU寄存器当中。(CPU和寄存器、内存是什么关系可以看看http://blog.csdn.net/sinat_31573679/article/details/55292476)
所以说左值一定可以作为右值,右值不一定能做左值。
作为左值,我们使用的是它的地址值,而作为右值,我们使用的是它的数据值,由此引出了第一点:
1.所以说表达式运算结果或单个变量应该是可以寻址的,即必须在内存中存在实体。(引用变量也不可寻址,但它永远只能是左值)
例如,表达式1+1就不可以作为左值。
2.常变量可以虽然可以寻址,但由于只读限制,也不能作为左值。
3.如果表达式的运算结果是一个临时的无名对象,则不能作为左值。
#include<iostream>
using namespace std;
int func(){
return 0;
}
int main(){
int i;
i+1=5; //错误1
func()=5; //错误2
}
之所以会出现错误1和错误2是因为i+1和func()的运算结果是一个临时无名的对象,无法寻址,所以并不能作为左值。
顺道提一下i++和++i
i++的实现是:int temp; temp=i; i=i+1; return temp,返回的是一个临时变量temp。所以i++不能作为左值。
++i的实现是:i=i+1; return i; 返回的是一个可寻址的变量。++i可以作为左值。
4.如果表达式运算结果或单个变量是一个引用的话可以作为左值。
#include <iostream>
using namespace std;
int global;
int &func(){
return global;
}
int main(){
int i =2;
(i+=1)=5; //正确1
func()=6; //正确2
cout<<i<<"";
cout<<global<<endl;
}
此时,i+=1的运算结果是对i的引用,func()返回的结果是对全局变量global的引用,故此两句均正确。
总结:1.根据变量或表达式运算结果的性质来判断是否能作为左值。
2.能建立引用的表达式一定能作为左值,不能作为左值的表达式只能建立常引用。