c中左值,右值

来源:互联网 发布:手机pdf修改软件 编辑:程序博客网 时间:2024/04/30 02:53

本文转载自:susan19890313的专栏 原文链接:http://blog.csdn.net/susan19890313/article/details/7446880

一.左值的概念

  lvalue 是指那些单一表达式结束之后依然存在的持久对象。例如: obj,*ptr, prt[index], ++x都是 lvalue。即左值表达式引用到一块已命名的内存区域,即左值表达式首先拥有一块内存区域,并且可以通过变量名来访问该内存区域。

rvalue是指那些表达式结束时(在分号处)就不复存在了的临时对象。例如:1729, x + y, std::string("meow"),和 x++都是 rvalue。在期待右值时,左值表达式会自动转化为右值

lvalue与 rvalue之分不在于表达式做了什么,而在于表达式代表了什么(持久对象或临时产物)。

示例:

(1)int a;

int foo(){return 1;}

foo的返回的是一个int,这个int的值是1,这个值是拥有存储的,但是你不应该知道;a + 1会通过+产生一个值,这个值是拥有存储的,但是这个存储也不是你应该知道的。所以,它们都不是左值。只有当你拥有表达式的存储的访问权时,你才可以把这个表达式放在=的左边,通过赋值来改变这个对象(在c中对象是指一块已命名的存储区域)的状态。

 

(2) C++左值与右值中前增量和后增量的区别

早期的c语言教材,for循环语句通常写成:

for(int i=0;i<10;i++)

而现在多为:

for(int i=0;i<10;++i)

两者有区别吗?

a++即是返回 a的值,然后变量 a加 1,返回需要产生一个临时变量类似于

{   

int temp = a;   

aa=a+1;   

return temp; //返回右值   

}  

++a则为:

{   

aa=a+1;   

return &a; //返回左值   

}  

显然,前增量不需要中间变量,效率更高。

++x和 x++的区别的语义上的区别:当写 int i = 10 ;时, i是一个 lvalue,它实际代表一个内存里的地址,是持久的。表达式 ++x也是一个 lvalue,它修改了 x的值,但还是代表原来那个持久对象。但是,表达式 i++却是一个 rvalue,它只是拷贝一份i的初值,再修改i的值,最后返回那份临时的拷贝,那份拷贝是临时对象。 ++i 和 i++都递增i,但 ++i返回i本身,而 i++返回临时拷贝。这就是为什么 ++i之所以是一个 lvalue,而 i++是一个 rvalue。

 

++(a--)

这个表达式是非法的,因为前增量操作要求一个可修改的左值,而 "a--"不是左值(即右值)

 

 

二.下列运算符的操作数必须为左值

取地址运算符 & , ++运算符, --运算符,赋值 =运算符的左操作数,成员 .运算符的左操作数。

 

 

三.如何判断那些由标识符和运算符共同构成的表达式是否是左值?

 

每种运算符都规定了它的运算结果是否是左值以及它的操作数是否期待左值,依据这些规则就可以判定一个表达式是否是左值(这些规则简称为左值规则)。

常见的左值规则

(1)最明显的左值表达式的例子是有适当类型和内存的标识符;

(2)间接运算符*的运算结果是左值;例如*ptr是左值

(3)取地址运算符&的运算结果是右值;例如&a是右值

(4)下列表达式不能产生lvalue:数组名,函数,函数调用,枚举常量,赋值表达式,强制类型转换(目标类型是引用时除外),。

原创粉丝点击