精华内容
下载资源
问答
  • 左值、左值表达式、左值引用 C++

    千次阅读 多人点赞 2019-06-25 20:10:31
    什么左值表达式、右值表达式 引用的分类 之前学习Java的时候只记得在赋值表达式左边的就是左值,右边的就是右值。这个说法没有错,但今天又在C++中有学习到了关于左右值得概念,在此梳理了一些这些知识点。 ...

    本文topics

    1. 什么是左值和右值
    2. 什么是左值表达式、右值表达式
    3. 引用的分类

    之前学习Java的时候只记得在赋值表达式左边的就是左值,右边的就是右值。这个说法没有错,但今天又在C++中有学习到了关于左右值得概念,在此梳理了一些这些知识点。

    左值和右值
    左值:左值是一个对象或变量,可以代表着一个固定地址。

    int i = 1;//此时,i是个变量,本质和对象一样,是一块内存区域,代表着一个固定的地址。
    

    右值:不能作为左值的都是右值,要么是一个常量,要么就是一个使用一次立即被销毁的临时变量或临时对象,右值没有固定的地址,使用完立即被释放。

    int i = 1 ; //1 是一个右值,没有固定地址,虽然它也占内存,但用完就被立即释放
    

    这里必须再提醒一下,左值也可以同时拥有右值属性,但反过来不行。

    i =i+5;//这里右边的虽然是个左值,但在这里有右值属性,可以理解为取出i的值和1相加构成一个值为(x+1)的常数(或者说临时变量)
    

    了解了什么是左值和右值,那么哪些地方可以用到呢?
    这里举介个常见运用左值的运算符的例子
    这些运算符都必须运用左值,无法用右值来运算。这里举几个常见的例子

    • 赋值运算符的左侧必须是左值,这个不用说应该都能理解
    • 取值符号&
    int i = 1;
    int* ptr = &i;//这里i必须是个左值
    
    • 容器的下标 [ ]
    string s=“daily coding";
    cout<<s[1]<<endl;//这里下标运算符的左边必须是左值
    
    • ++,- -等。这里有统一方法可以看一个运算符是不是必须用左值。就是看这个运算符能不能操作字面值,如果不可以,就是左值运算符。
    3++;//错误,这种直接操作一个字面量显然不行,所以++是必须运用左值的运算符
    

    左值表达式和右值表达式
    这个很好理解,一个表达式的求值结果如果是左值,就是左值表达式,否则如果是右值,就是右值表达式

    int i = 1;
    ++i = i+2;
    //这里左边++i,是返回一个i的变量,但i的值增加了1,所以是左值表达式
    //这里i+1是一个右值表达式 ,因为它是一个存了3的临时地址,赋值给i++后就被释放了。
    
    i++ = i + 2;//错误,因为i++是一个右值表达式,这里可以理解为 有一个临时对象temp=i;i = i+1;然后返回temp,结果就等于 1  =i+1;所以显然不行 
    

    引用分类

    • 左值引用
      即绑定到左值的引用,必须绑定左值
    int i = 1;
    int &ref = i;//这里ref是绑定了i这个左值的引用
    int &ref2 = 3;// 3 是右值,无法绑定
    
    • 右值引用
      右值引用的作用是给开发者提供一个想要可以绑定临时变量的作用,可以通过右值引用符号“&&” 来实现
    int &&i=1;//右值引用可直接引用右值,可以理解为想要给 “ 1 ”一个固定的地址,并给与一个变量名i
    i = 3;//可以通过i再赋值
    
    • Const常量引用,本质上也是左值引用的一种,但区别有二
      一是无法通过这个引用改变引用地址的值,二是它可以间接绑定右值(实际上是绑定了一种左值)
    int i = 1;
    const int &ref = 1;
    i = 10;//错误,无法再赋值 ,因为ref是一个常量引用
    
    const int &ref2 = 100;//可以引用一个右值,本质上是将100转换为一个变量,再将ref2引用到这个变量上
    

    总结

    1. 左值是一个对象或变量,代表一个固定地址,而没有固定地址的临时对象或临时变量既是右值,不能代表一个固定地址
    2. 左值表达式就是一个值为左值的表达式,右值表达式就是值为右值的表达式
    3. 左值引用只能引用左值,右值因为只能引用右值,而const引用就可以同时引用左值和右值(通过临时变量间接引用右值,实际上是左值引用)
    展开全文
  • C++左值表达式

    千次阅读 2014-03-06 21:39:32
     或许你是从书中了解到这个概念,有些老书可能会写左值表达式就是可以放在赋值运算符左侧作为左操作数的表达式,这种说法在早期或许是没什么问题的,毕竟早期的左值定义是基于赋值运算符需求的,它认为能作为赋值...

        今天我们将要谈论的话题——左值表达式——相信不少人从各种途径中或许了解到一些,若是对这个概念还是模模糊糊,那接着看下去就对了,若是对这个概念十分清楚了,那就帮我找找问题,不吝赐教一下吧!

        或许你是从书中了解到这个概念,有些老书可能会写左值表达式就是可以放在赋值运算符左侧作为左操作数的表达式,这种说法在早期或许是没什么问题的,毕竟早期的左值定义是基于赋值运算符需求的,它认为能作为赋值运算符左操作数的表达式就是左值。但这个说法也有一些地方将难以自圆其说,比如数组名,数组是聚集,不是标量类型(标量类型,实际上指的就是C++基本类型,如int, char之类),我们是无法用一个值来表示一个数组的,而赋值运算符则要求左操作数是一个标量类型(结构例外),这显然不合理。因此,早期将数组名定为右值,数组作为完整对象,理应可以取地址,但取地址运算符又要求操作数为左值,这与定义又矛盾了。

        说了左值过去的说法,那现在就来讲讲左值现在的说法吧!我们判断一个表达式是否为左值表达式,关键在于:它必须指示一个对象,不管这个对象是有效还是无效,完整还是不完整(关于完整类型,不完整类型下面会提到),另外加一点,在C++中,规定包括非静态类成员函数之外的函数都是左值表达式。下面举个例子:

    int i;
    int *p = &i;


     

    我们且不管p指向的i内容有效无效,i和p都是指示一个对象的,且具有对象类型,所以它们都是左值,但是虽然&i也有对象类型,但是它并没有指示一个对象,所以它不是左值。这里或许有些人会感动迷糊,&i不是表示了一个地址了么,怎么说是没有指示一个对象呢?在这里,我就引用一句李普曼大师在C++ Primer5里写到的一句话:变量是左值!注意这里的变量说的可不是临时变量!我们应该严格区别一下。由此,我们再看上面,&i是一个临时变量,所以它不算是左值!

        我们在上面提到过完整类型和不完整类型,不完整类型其实就是缺少足够的信息,举个例子,比如缺少定义以致不能明确其大小,前向声明也算是常见的一种不完整类型:

    class MyClass;
    struct S;

    看到这里,大家都恍然大悟了吧,原来是这种玩意儿!

    展开全文
  • 左值表达式:该表达式的运算结果是一个左值 以下是C艹中的几个例子: int a=0; a=3;//正确,此处a是左值 //a最后的值为3 const int a=0; a=3;//错误,此处a为常变量,不允许被再次存放,不能当左值 //a赋值错误 ...

    左值:具有存放数据的空间且允许存放
    左值表达式:该表达式的运算结果是一个左值
    以下是C艹中的几个例子:

    int a=0;
    a=3;//正确,此处a是左值
    //a最后的值为3
    
    const int a=0;
    a=3;//错误,此处a为常变量,不允许被再次存放,不能当左值
    //a赋值错误
    
    int a=0,k=1;
    	++a=k;//正确,因为它使a的值+1,运算结果依然是变量a,所以++a是左值表达式
    //a最后的值为k的值1
    
    int a=0,k=1;
    	a++=k;	//错误,因为a++的运算结果是一个临时变量,
    			//而这个临时变量并不是你程序中定义的可寻址变量的引用,不能被更改,不能作为左值表达式
    //a赋值错误
    
    int a=0,k=1;
    (a=k)=3;//正确,先执行(a=k),这个赋值表达式的运算结果依然是变量a,数值上等于k的值,因此可以作为左值表达式
    //a最后的值为3
    

    总之,左值都可以被赋值,由于左值表达式返回一个左值,因此也可以对其赋值。

    展开全文
  • 左值表达式 右值表达式(C/C++)

    千次阅读 2015-01-19 17:43:59
    达式(也只能对左值表达式和函数)取址运算时,可以获得该对象的地址 (有两种左值表达式不能取址,一是具有 位域( bit-field )类型 ,因为实现中 最小寻址单位是 byte;另一个是具有 register指定符...

    何谓对象?

    这里所说的对象是广义上的,而不仅仅是狭义的类/对象(class/object)。

    C/C++,所谓的对象指的是执行环境中一块存储区域(a region of storage),
    该存储区域中的内容代表了该对象的值(value)。注意到我们这里所说的"
    ",对于一个对象,如果我们需要取出它的值,那么我们需要通过一定的

    类型(type)来引用它。使用不同的类型,对同一对象中的内容的解释会导致

    可能得到不同的值,或者产生某些未定义的行为。

     何谓变量?

     经常有人会把变量与对象二者混淆。所谓变量是一种声明,通过声明,

    把一个名字与一个对象对应起来,当我们使用该名字时,就表示了我们对该

    对象进行某种操作。但是并不是每个对象都有名字,也并不意味着有对应的

    变量。比如临时对象(temporary object)就没有一个名字与之关联(不要误称

    为临时变量,这是不正确的说法)。

    左值 右值

    先看一个例子(出自《C专家编程》)

    一个赋值表达式:      X = Y;

    在这个表达式里,符号X的含义是X所代表的地址,这被称为左值,左值

    在编译时可知,左值表示存储结果的地方;

    在这个表达式里,符号Y的含义是Y所代表的地址的内容,这被称为右值,

    右值在运行时才可知,如无特别说明,右值表示“Y的内容

    按照C的定义,左值是一个引用到对象的表达式,通过左值我们可以取出

    该对象的值。通过可修改的左值表达式(modifiable lvalue)我们还可以修改

    该对象的值。(需要说明的是,在C++中,左值还可以引用到函数,即表达

    式f如果引用的是函数类型,那么在C中它既不是左值也不是右值;而在

    C++中则是左值)。因为左值引用到某一对象,因此我们使用&对左值表

    达式(也只能对左值表达式和函数)取址运算时,可以获得该对象的地址

    (有两种左值表达式不能取址,一是具有位域( bit-field )类型,因为实现中

    最小寻址单位是 byte;另一个是具有register指定符,使用register修饰的变

    量编译器可能会优化到寄存器中).

      与左值相对应的另一个概念是右值(rvalue)。在C中,右值也用表达式的

    值(value of the expression)来表达。即右值强调的不是表达式本身,而是

    该表达式运算后的结果。这个结果往往并不引用到某一对象,可以看成

    计算的中间结果;当然它也可能引用到某一对象,但是通过该右值表达

    式我们不能直接修改该对象。

    关于++i 和 i++

     ++i的实现:++i是直接给i变量加1,然后返回i本身,因为i是变量,

    所以可以被赋值,

             即  int & ++(& i)
    
     {
    
      i=i+1;
    
    return i;
    
    }             
    
    当然,以上代码只是说明问题,不能运行,只是说明++i是左值表达式
    
     
    
     i++的实现:
    
    int ++(int i)
    
      {
    
            int temp=i;
    
              i=i+1;
    
             return temp;}
    
     
     
    
    返回临时对象,然后临时对象不存在了,所以,不能再被赋值,因此
    
    是右值表达式
    展开全文
  • 左值具有对象或不完整类型,在C++中还具有函数或引用类型,但是,并非具有上述类型的表达式就是左值,关键是左值必须指示一个对象,无论该对象有效或无效、完整或不完整,在C++中则包含非静态成员函数之外的函数。...
  • 转载自 飞天御剑流 的博客 ... C/C++左值性精髓 ...(二)哪些表达式左值,哪些是右值?...C++由于增加了引用类型,结果为引用的函数调用表达式和强制转换表达式都属于左值,示例如下:   int& fun1( int & r
  • 表达式左值右值

    2015-09-17 19:10:00
    左值右值是表达式的属性,该属性称为 value category。按该属性分类,每一个表达式属于下列之一: lvalue left value,传统意义上的左值 xvalue expiring value, x值,指通过“右值...
  • 1. 左值表达式    如上一节所述,左值具有对象或不完整类型,在C++中还具有函数或引用类型,但是,并非具有上述类型的表达式就是左值,关键是左值必须指示一个对象,无论该对象有效或无效、完整或不完整,...
  • c++11支持用decltype推断变量/表达式的类型,与auto推断不同,decltype并不会计算表达式的值。 decltype会准确的返回变量/表达式的类型,即使是数组这种比较复杂的类型也不例外。 ...
  • C++表达式左值

    2017-11-18 09:18:12
    表达式 在C++中,任何值或者任何有效值和运算符号的组合都是表达式 。 对任何表达式加上分号都可以成为语句。 如: 当判断表达式的值这种...x=20//表达式的值为20x二左值 可以通过以下两点来判定C++中的左值 1 有名
  • 关于C++表达式左值

    2019-09-22 19:06:11
    表达式是否保留左值性视需要而定,这个“需要”是什么? 其实是C++某些运算符的强制规定,例如内置赋值运算符、前置增量和前置减量运算符等等,这类运算符的结果被强制规定为左值,对于条件运算符,只有第二和第三...
  • 表达式作为左值

    千次阅读 2018-09-28 20:30:09
    示例代码: #include using namespace std; ...1、第一个函数返回的是一个数,所以不能作为左值 ...2、第二个函数返回的是一个变量(a的引用),所以可以作为左值 3、修改函数的值就相当于修改a的值
  • a == 'a'这个比较运算,得到一个bool类型的值(可理解为匿名值b),然后将 b(bool) || a(variable),又得到一个bool类型的值(c),最后进行赋值运算c = 'a',所以才会出现(赋值)表达式必须是可修的左值,而...
  • 赋值表达式左值和右值

    千次阅读 2019-03-26 21:23:55
    一般出现在赋值表达式的左边,但也可以出现在赋值表达式的右边。其特点是有变量名即可通过地址访问并修改的内存块 右值 只能出现在赋值表达式的右边,特点是没有名字,即没有可访问的地址名,只有一个值 常规...
  • 上篇我们学习了变量以及变量的使用,...它的作用是将一个表达式的值赋给一个左值。所谓左值是指一个能用于赋值运算左边的表达式左值必须能够被修改,不能是常量。这个是基本的赋值运算符。例如班级里a同学成绩是8...
  • C语言条件表达式左值

    2020-03-23 09:51:33
    ((a > 5)? b:c) = 100;
  • 参考回答: 右值引用是C++11中引入的新特性 , 它...左值:能对表达式取地址、或具名对象/变量。一般指表达式结束后依然存在的持久对象。 右值:不能对表达式取地址,或匿名对象。一般指表达式结束就不再存在的临时对...
  • 左值引用先看一下传统的左值引用。int a = 10; int &b = a; // 定义一个左值引用变量 b = 20; // 通过左值引用修改引用内存的值左值引用在汇编层面其实和普通的指针是一样的;定义引用变量必须初始化,因为引用...
  • 在练习时遇到这个问题 struct CandyBar { char name[50]; double weight; int caloria; };...oid put_in(CandyBar& candy, char* name, double weight, int caloria) ...由于name是字符数组,不可直
  • 是正常的赋值表达式,a是左值,b+23是右值。 在赋值表达式中,左值是变量,是要将a的值改变为另外的值; 右值是常量,是不可改变的量,b在定义的时候就已经有了初始值 (计算机随机分配的值)。所以b+23在计算机...
  • "左值"是什么

    千次阅读 2014-09-29 22:05:23
    像这样,表达式表示某处内存区域的时候,我们称当前的表达式左值(lvalue);相对的,表达式只是代表值的时候,我们称当前的表达式为右值。 在标准委员会的定义,lvalue的l不是left的意思,而表示 ...
  • <p>void Change(string &s,const string &oldVal,const string &newVal) {<!-- -->  auto l =...报错表达式必须是可修改的左值,把const string改成string仍然没有用。</p>
  • 转载自:...按该属性分类,每一个表达式属于下列之一:lvalueleft value,传统意义上的左值xvalueexpiring value, x值,指通过“右值引用”产生的对象prvaluepure rvalue,纯右值,...
  • C语言中左值和右值概念是来自赋值或复合赋值表达式。初学者会很容易迷惑,这里给出这两个概念总结。对于赋值表达式E1=E2,其中E1必须是可修改的左值,E2是右值。左值:简写lvalue,left value右值:简写rvalue,right ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,810
精华内容 9,124
关键字:

左值表达式是什么意思