代码改变世界

r-value(Rvalue) 和l-value(Lvalue)

2004-08-02 11:44  FantasySoft  阅读(4039)  评论(7编辑  收藏

        在写引用类型与指针的比较这篇随笔的时候,我写了一些试验性的代码以检验一些结论是否正确。
        首先,引用是一个const的指针(注意不是指向const object的指针),所以在声明一个引用的同时必须
对这个引用进行初始化。因此

int &b;

编译不能通过是自然而然的事情,错误信息是:references must be initialized。多事的我就想,既然是const的指针,那我能不能这么写呢:

int * const b; 

结果错误信息变成了const object must be initialized if not extern。接着我再给这个statement加了个extern。OK,编译错误没有再出现了,接着,我给这个指针进行赋值。结果出现了这样的编译错误:
        l-value specifies const object

        到此为止,我看到了一个似懂非懂的东西l-value。 到底什么是l-value呢?我第一时间想到左结合了,譬如说"hello" + "world" + "!" 等价于("hello" + "world") + "!"。由此推广,我可以想到的左值的一个解释就是:在赋值的时候,"="运算符左边的就是左值了。
        而事实上,我的猜测也是基本正确的。左值必须引用于某个对象,而对于赋值运算符,它的左操作数必须是一个左值(lvalue expression must refer to an object.For the assignment to be valid, the left operand must refer to an object-it must be an lvalue. [1] );而右值(rvalue)则是具体的数字型或是字符型的值(Every expression is either an lvalue or an rvalue." So an rvalue is any expression that is not an lvalue. [1])。
      
        以下是对于左值和右值在使用上的几个要点:
        1、右值是不能转化为左值的,而反过来,则是可以的。如:    

int a, b;
= b;

              a和b都是左值,但是b出现在了赋值运算符的右边。编译器在编译过程中做了左值到右值的转换。    
        2、"+"运算符的操作数没有左值或是右值的限制,但是运算的结果却是右值。比如说:

(m + 1= n;

              是会发生编译错误的,因为m + 1是右值;
        3、"&"运算符的操作数必须是左值,而结果也是右值(注意这是取址运算符哦,别跟引用搞混了);
        4、"*"运算符的操作数则左值或着右值,其结果则是左值,如

int a = 2;
int *= new int[3];
*= a;
*(p+1= 3;

       [1] Lvalues and Rvalues