对于左值和右值还有一些模糊的地方:
书上说左值(L-value)是指地址值,右值(R-value)是指数据值。
但对于***右值指的是引用了一个存储在某个内存地址里的数据***这句话不是特别清楚,比如说:a = 5,
1、数值5是来自于内存中的某个特定存储区域吗,而且无论数值大小均是这么来的吗(记忆中好像不是的呢)?
2、使用数值5的时候是以copy的方式还是其他的方式得到的?
3、或者是在赋值之前临时创建的大小为int的空间来存储5,并非是从内存中的引用?
4、关于这方面有什么相关的书籍推荐么?
先谢谢各位不吝赐教。
不太清楚题主问的是 C 还是 C++,如果是 C++ 的话,是哪一版标准的 C++。我这里只说 C++11 中关于左值和右值的问题。
粗略的来讲,当一个对象被用作右值(rvalue)的时候,使用的是这个对象的值(它的内容);当一个对象被用作左值(lvalue)的时候,使用的是这个对象的身份(它在内存中的位置)。
对于表达式
a = 5;
,假设a
为int
类型。其中等号左边的表达式a
的类型是左值,因为我们需要用到它的身份(它在内存中的位置),才能把值赋给它。等号右边的表达式5
的类型是右值,因为我们需要用到它的值(它的内容)。数值
5
是 一个 literal,它的类型是右值(更准确的说是 prvalue,见下文),应该是保存在静态内存(static memory)中。无论大小,只要是 literal 都如此,例如2333333333333333ULL
。在表达式
a = 5;
中,应该是内置赋值运算符将5从静态内存复制到变量a
中。对于自定义的赋值运算符,就要看:1. 是否定义了拷贝赋值运算符(copy-assignment operator)和移动赋值运算符(move-assignment operator),2. 等号右侧表达式的值类型,从而确定是拷贝还是移动。
不是。
不清楚有没有专门论述这方面的书籍,不过你可以看看本文末尾参考部分的文档和 C++11 标准。
以下为引申内容。
前提
C++ 中的表达式(expression,例如操作符和它的操作数、变量名等)是根据两个方面进行分类的:类型和值类别。每个表达式都必定属于三个主要值类别(见下文)之一。
C++11 中表达式的值类别
在 C++11 之前,表达式的值类别分为左值(lvalue)和右值(rvalue)两种,而自 C++11 起,表达式的值类别分为 lvalue、xvalue、prvalue、glvalue、rvalue 五种。之所以引入了这么多种值类型,是因为 C++11 中新增的移动语义(move semantics)。
他们之间的关系如下图所示:
表达式的值类别分类的标准是两点:
有无身份(has identity) 即是否能通过比较两个表达式的身份判断他们是否是同一个表达式。
能否被移走(can be moved from) 即能把表达式的值移到其它变量中去,使原变量处于一种不确定但有效的状态(例如能正常析构)。
这5个值类别之间的关系如下表所示:
C++11 标准原文
From C++11 standard § 3.10
参考
C++ 中表达式的值的类别:Value categories
C++ 中值分类名称的变化由来:“New” Value Terminology
C++0x 到 C++11 值分类名称的变化:n3055