C++的左值和右值问题

robin_yao 2006-09-30 11:14:39
以下文字是摘自《C++ Primer 3rd Edition》-- page76
“变量和文字常量都有存储区,并且有相关的类型。区别在于变量是可寻址的
(addressable) 对于每一个变量都有两个值与其相关联:
1.它的数据值,存储在某个内存地址中。有时这个值也被称为对象的右值(rvalue ,读
做are-value)。 我们也可认为右值的意思是被读取的值(read value)。 文字常量和变量都可
被用作右值。
2.它的地址值——即存储数据值的那块内存的地址。它有时被称为变量的左值(lvalue,
读作ell-value)。 我们也可认为左值的意思是位置值location value。 文字常量不能被用作
左值
在下面的表达式中:
ch = ch - 'O';
变量ch 同时出现在赋值操作符的左边和右边。右边的实例被读取,与其相关联的内存中
的数据值被读出。左边的ch 用作写入。减操作的结果被存储在ch 的位置值所指向的内存区
中,原来的数据值会被覆盖。在表达式的右边,ch 和文字字符常量用作右值。在左边,ch
用作左值。


为什么 左边的ch是 左值 呢?

不理解。请详细解释一下。
下面还有篇文章:
http://dev.csdn.net/develop/article/19/19165.shtm
没看懂!
...全文
903 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
OOPhaisky 2006-09-30
  • 打赏
  • 举报
回复
左值和右值的概念的确很容易让人迷糊。
楼主记住两点:
1.左值是类似于地址的东西,根据它可以找到具体“装载”着的对象,而右值就是具体“装载”着的对象。
2.对左值和右值的理解应该适可而止,不要太深入追究,以免走火入魔。
blue_zyb 2006-09-30
  • 打赏
  • 举报
回复
从来不顶人,今天一定要顶一下weijiangshanwww() ,讲得挺不错!赞

有两个问题请教:
1. >> "因为 C++ 中对象也可能是一个非左值,即右值。"
你指的临时对象吗还是?那C标准中对于函数返回一个结构体是作为左值处理的吗?

2. 在C++中,你认为进行常量折叠的普通const量,例如const int size = 10; (也就是说没有
在程序的地址空间中为size分配存储), 从"概念上"说是l-value吗?

taodm 2006-09-30
  • 打赏
  • 举报
回复
呃,偶的意思是:搞那么极其精确干嘛。不值得于此多浪费时间。
只要知道编译器报需要lvalue错误一般都是你传了个临时对象或者常量对象。
跳过吧,学其它更重要的知识。

huangyangman 2006-09-30
  • 打赏
  • 举报
回复
感觉LZ给的材料已经很详细拉,你问的答案全在你给的材料里了
我的建议是先记下来吧,等以后回头看时会觉得很明了的
有句话叫只可意会不可言传来着。
帮顶吧
飞哥 2006-09-30
  • 打赏
  • 举报
回复
可以看看msdn的说明
L-Value and R-Value Expressions
Expressions that refer to memory locations are called “l-value” expressions. An l-value represents a storage region’s “locator” value, or a “left” value, implying that it can appear on the left of the equal sign (=). L-values are often identifiers.

Expressions referring to modifiable locations are called “modifiable l-values.” A modifiable l-value cannot have an array type, an incomplete type, or a type with the const attribute. For structures and unions to be modifiable l-values, they must not have any members with the const attribute. The name of the identifier denotes a storage location, while the value of the variable is the value stored at that location.

An identifier is a modifiable l-value if it refers to a memory location and if its type is arithmetic, structure, union, or pointer. For example, if ptr is a pointer to a storage region, then *ptr is a modifiable l-value that designates the storage region to which ptr points.

Any of the following C expressions can be l-value expressions:

An identifier of integral, floating, pointer, structure, or union type


A subscript ([ ]) expression that does not evaluate to an array


A member-selection expression (–> or .)


A unary-indirection (*) expression that does not refer to an array


An l-value expression in parentheses


A const object (a nonmodifiable l-value)
The term “r-value” is sometimes used to describe the value of an expression and to distinguish it from an l-value. All l-values are r-values but not all r-values are l-values.

Oversense 2006-09-30
  • 打赏
  • 举报
回复
ch = ch - 'O';
左边这个ch是左值
右边这个ch是右值
weijiangshanwww 2006-09-30
  • 打赏
  • 举报
回复
要准确理解左值和右值的概念,首先需要明确我们指的是 C 还是 C++ 中的左值或右值。这是因为 C 和 C++ 对于左值及右值的定义是有区别的。另外,左值和右值的概念人为规定的成份很大,往往给出的定义不能囊括所有情况。

>> 《TCPL》A.5:An object is a named region of storage, an l-value is an expression referring to an object.

对于 C 语言来说,这个定义就不是太准确,特别在 C99 标准出台之后更是如此。这个定义中规定了“对象(object)”是“有名存储区(a named region of storage)”。且不说动态分配的内存(无名存储区)能否作为对象,只就 string literal 以及在 C99 中新增加的 Compound litertal 而言(它们都是对象,并且都是左值,但是又都是没有名字表示的),就不在上述定义的界定范围之内。

对于 C++ 来说,这个定义就更不适用了。因为 C++ 中对象也可能是一个非左值,即右值。同理,ISO/IEC9899 中为 C 语言提供的左值的定义也不适用于 C++。

>> "lvalue"还可以分为一般的"lvalue"和"modifiable lvalue"。

这句话说得比较别扭。是否可改为 "lvalue" 还可以分为"modifiable lvalue" 和 "unmodifiable lvalue"?

>> "lvalue"必须对应于一块确定的内存空间,并且在编译时已经确定了

《ISO/IEC9899 WG14/N1124》P58:An l-value is an expression with an object type or an incomplete type other than void.

根据上述定义,对于非 void 的非完整类型(incomplete type)的引用也是左值;而我们知道在程序中对于非完整类型是不能进行引用的,否则会在编译时产生错误。

因此,左值只是对应着某一存储空间,而与此存储空间是否真实存在、是否能够实际访问无关,更谈不上是在编译时确定的了——这显然否定了动态分配的对象也可以是左值。

>> "lvalue"可以作为"rvalue",但是"rvalue"不一定可以作为"lvalue"来使用。

左值和右值的概念是对立的,即非左即右(根据C++标准对左值的定义,C标准没有明确这么说)。左值可以作为右值是因为 C 和 C++ 标准中规定的 lvalue-to-rvalue 转换所致,但是右值不是“不一定”、是一定不能作为左值来使用。

>> 它是"lvalue"而且还是"modifiable lvalue",要不然如何初始化呢?

左值对象都可以被初始化,即使是对于不能改变的左值也是如此。否则,如果不能初始化你又如何使用它呢?因为未初始化就使用是非法的。显然上面一句的“初始化”应该是“赋值”的笔误。
healer_kx 2006-09-30
  • 打赏
  • 举报
回复
左边的就是左值,右边的就是右值呗。。。
robin_yao 2006-09-30
  • 打赏
  • 举报
回复
up

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧