最近在研究C++ 左值 右值,搬运、收集了一些别人的资料,供自己记录和学习,若以后看到了更好的解释,会继续补充。(打“?”是我自己不明白的地方 )

 
参考:《Boost程序库探秘——深度解析C++准标准库(第2版)》 9787302342731
 
左值:一个可以用来存储数据的变量,有实际的内存地址(变量名);
右值(非左值):“匿名”的“临时”变量,在表达式结束时生命周期终止,不能存放数据,可被修改,也可不被修改(const修饰)。
 
鉴别左值右值:
左值可用取地址操作符&获取地址,右值不行,会发生编译错误。
 
所有c++的表达式的结果不知左值就是右值(?)
++i 是左值,i++ 右值(返回的是一个临时变量,无法赋值);(?)
 
可以把右值得内容转移到其他的对象中去,从而完全消除了之前昂贵的拷贝代价;
 
T&    左值引用;
T&& 右值引用(C++11)。
 
c++ primer 3rd
只有在必要的时候才使用后置操作符(i++),
前置操作符返回的是左值(对象本身),而后置操作符返回的是右值。前置操作符需要的工作更少,只需加1后返回加1后的结果;而后置操作符则必须先保存原来的数值,以便返回未加1时的值,可能会花费更大的代价。
所以建议 ++i 。
 

MSDN

Lvalues 和 Rvalues

Visual Studio 2013 版本
 

每个 C++ 表达式是左值或右值。 左值是指在单个表达式的外部保留的对象。 可以将左值视为具有名称的对象。 所有变量(包括不能更改的 (const) 变量)都是左值。 左值是一个不在使用它的表达式的外部保留的临时值。 若要更好地了解左值和右值之间的区别,请考虑下面的示例:

 
// lvalues_and_rvalues1.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
int main()
{
int x = + ;
cout << x << endl;
}

在此示例中,x 是左值,因为它在定义它的表达式的外部保留。 表达式 3 + 4 是为一个右值,因为其计算结果为不在定义它的表达式的外部保留的临时值

以下示例演示左值和右值的多种正确的和错误的用法:

// lvalues_and_rvalues2.cpp
int main()
{
int i, j, *p; // Correct usage: the variable i is an lvalue.
i = ; // Incorrect usage: The left operand must be an lvalue (C2106).
= i; // C2106
j * = ; // C2106 // Correct usage: the dereferenced pointer is an lvalue.
*p = i; const int ci = ;
// Incorrect usage: the variable is a non-modifiable lvalue (C3892).
ci = ; // C3892 // Correct usage: the conditional operator returns an lvalue.
((i < ) ? i : j) = ;
}

说明

此主题中的示例阐释了未重载运算符时的正确和错误用法。 通过重载运算符,可以使表达式(如 j * 4)成为左值。

当引用对象引用时,通常会使用术语“左值”和“右值”。 有关引用的详细信息,请参阅Lvalue 引用声明符:& 和规则引用声明符:&&


c++ primer
 
当一个对象被用作右值时,用的是对象的值(内容);当对象被用做左值的时候,用的是对象的身份。
 
原则:需要右值的地方可以用左值代替,但不能把右值当成左值(位置)来使用。
 
当一个左值被当成右值使用时,实际使用的是它的内容。

C++ 左值 右值的更多相关文章

  1. c++ 左值右值 函数模板

    1.先看一段代码,这就是一种函数模板的用法,但是红色的部分如果把a写成a++或者写成一个常量比如1,都是编译不过的,因为如果是a++的话,实际上首先是取得a的 值0,而0作为一个常量没有地址.写成1也 ...

  2. C++ 左值与右值 右值引用 引用折叠 => 完美转发

    左值与右值 什么是左值?什么是右值? 在C++里没有明确定义.看了几个版本,有名字的是左值,没名字的是右值.能被&取地址的是左值,不能被&取地址的是右值.而且左值与右值可以发生转换. ...

  3. 左值&右值

    一.引子 我们所谓的左值.右值,正确的说法应该是左值表达式.右值表达式. 因为C++的表达式不是左值就是右值. 在C中,左值指的是既能够出现在等号左边也能出现在等号右边的表达式,右值指的则是只能出现在 ...

  4. C++11之右值引用(一):从左值右值到右值引用

    C++98中规定了左值和右值的概念,但是一般程序员不需要理解的过于深入,因为对于C++98,左值和右值的划分一般用处不大,但是到了C++11,它的重要性开始显现出来. C++98标准明确规定: 左值是 ...

  5. C语言几个术语: 数据对象,左值,右值

    1. 数据对象 赋值表达式语句的目的是把值存储到内存位置上. 用于存储值的数据存储区域统称为数据对象. 2. 左值 左值是C语言的术语, 用于标识特定数据对象的名称或表达式. 对象指的是实际的数据存储 ...

  6. i++和++i以及左值,右值

    左值(LValue)和右值(RValue)的一个快捷记法是赋值运算,左值是赋值运算左边的值,右值就是右边(=,=废话).例如: int a = 5; a就是左值,5就是右值. 当然,如果真是这么个含义 ...

  7. C和C指针小记(八)-操作符、左值右值

    1.移位操作符 移位操作符分为左移操作符(<<)和右移操纵符(>>) 对于无符号数:左右位移操作都是逻辑位移 对于有符号数:到底是采用逻辑位移还是算术位移取决于编译器.如果一个 ...

  8. C++中的左值与右值(二)

    以前以为自己把左值和右值已经弄清楚了,果然发现自己还是太年轻了,下面的这些东西是自己通过在网上拾人牙慧,加上自己的理解写的. 1. 2. 怎么区分左值和右值:知乎大神@顾露的回答. 3. 我们不能直接 ...

  9. C语言 左值、右值

    左值就是在赋值中可以放在赋值操作符两边的值 右值则是只可以放在赋值操作符右边的值 ++i是直接给i变量加1,然后返回i本身,因为i是变量,所以可以被赋值,因此是左值表达式i++现产生一个临时变量,记录 ...

随机推荐

  1. cyq.data开源

    终于等到你:CYQ.Data V5系列 (ORM数据层)最新版本开源了 前言: 不要问我框架为什么从收费授权转到免费开源,人生没有那么多为什么,这些年我开源的东西并不少,虽然这个是最核心的,看淡了就也 ...

  2. 微软http api说明书地址

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa364622(v=vs.85).aspx https://msdn.microso ...

  3. Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer'

    @Configuration public class HttpSessionConfig { @Bean public static ConfigureRedisAction configureRe ...

  4. paip.php-gtk 桌面程序 helloworld总结

    paip.php-gtk 桌面程序 helloworld总结 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.cs ...

  5. SSH框架入门学习之二(spring)

    Spring也是一个开源框架,我在学习Spring的时候,认为最重要的几点是:IOC(控制反转).AOP(面向切面)和容器概念. 详细的教程还请大家去看网上的视频,这里贴一个小Demo以供学习. (前 ...

  6. Javascript 学习 笔记一

    1.操作 HTML 元素        如需从 JavaScript 訪问某个 HTML 元素,您能够使用 document.getElementById(id) 方法.        请使用 &qu ...

  7. js实现无限级树形导航列表

  8. Acitivity的一些属性配置

    转自:http://blog.csdn.net/javayinjaibo/article/details/8855678 1.android:allowTaskReparenting 这个属性用来标记 ...

  9. CentOS服务器下对mysql的优化

    原文链接: CentOS服务器下对mysql的优化 一.mysql的优化思路 mysql的优化分为两方面: 1. 服务器使用前的优化 2. 服务使用中的优化 二.mysql的基础优化步骤 1. 硬件级 ...

  10. HDU 5012 Dice DFS

    简单DFS //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h ...