本文主要是介绍逻辑自洽地区分【左值与右值】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
由于不同的文章和书籍,对左值和右值的区分皆有不同,这里我只是给自己定了一个逻辑可以自洽的标准,供自己去区分左值和右值,所以本篇博客,属于一个笔记。
C++ primer对左值和右值的介绍
C++中的表达式:要么是左值,要么是右值。而左值和右值是从C语言中继承过来的,在C语言中,为了帮助记忆,可以简单的认为左值可以位于赋值语句的左侧,右值则不能。这里其实也表达了一个隐藏的性质:左值可以被修改,右值不可以被修改。
但是在C++中,左值和右值的区分就复杂了很多,这也就是不同的文章、资料和书籍对左值和右值区分有不同的说法的原因。
C++primer:“一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象”
这句话的意思就是左值是一个指明对象的表达式,“常量对象不能做赋值语句的左侧运算对象”的意思就是const 左值,即使不可修改,但是依旧是左值。也就指出:左值分为可修改的左值和不可修改的左值(常量对象/const 左值)
C++primer:“虽然某些表达式的求值结果是对象,但它们是右值而非左值”
这句话意思,即使你的表达式结果指向的是一个对象,但是你位于赋值表达式的右侧,那这个对象就被当作右值,此时用到的是对象的值,也就是用的对象的内容,并不是这个对象。
最后其总结了一句话:“当一个对象被用作右值时,用的是对象的值(内容);当对象被用作左值时,用的是对象的身份(对象在内存中存储的位置)”
这也表达了一个观点:左值可以当右值使用,但是此时用的是左值指向的对象的内容,但是右值不能当左值使用,因为左值必须指明一个对象,右值压根没有指明的对象。
在了解这些之后,下面是总结的左右值的概念和区分
一、左值(可修改的左值 、不可修改的左值)
左值:用来指明一个对象的表达式,指向这个对象的内存区域,可以被取地址
我们思考一下,左值一般用来干什么?
我们在使用左值的时候,无非就是在赋值,将左值改变,那既然是要改变左值,就必须要求左值指明一个对象,也就必须要求左值要拥有存储空间,可以被取地址。(没有空间怎么改变?)
特殊情况:不可被改变的左值
const 修饰的左值,不可被修改,不能出现在 ‘ = ’的左侧,但仍是左值
证明1:
因为左值是 有指明的对象,有存储空间且可以被取地址的,所以即使被const修饰,依旧满足上面的条件
证明2:(C++语法)
使用左值引用与右值引用来证明
const int x = 10;// x = 12; //虽然x不可出现在 ‘ = ’的左边// const int&& y = x; //右值引用无法引用const int& z = x; //左值引用可以引用,但必须是const,要保证权限
// 从语法上证明,x仍为左值
二、右值(都不可被改变)
右值:表示一个值但不指明一个对象的表达式,不可以被取地址;如:字面常量,表达式,数组名,函数名,临时对象等
数组名、函数名为右值原因:
数组名与函数名都是地址常量,没有指明的空间存储,所以为右值;
临时对象为右值原因:
首先要知道临时对象是如何产生的?
临时对象一般是在 类型转换、对象拷贝的时候生成的,其任务就是将值拷贝一份,再赋值给接收对象。赋值结束后,临时对象也就销毁了,所以其生命周期的短暂,我们无法取到其地址,就认为临时对象是一个将亡值,被当作右值。
在C++11引入右值引用之后
C++primer 提到了:“左值持久,右值短暂”的说法,也就是左值有持久的状态,右值是非持久的状态。这也正对应了上面所说的,左值可以取地址,右值不可以。因为我们没有理由去取一个即将销毁的变量的地址,是没有意义的。所以在取右值的地址时,在编译的时候也是会报错的。
综上所述,总结了区分左右值并且逻辑自洽的观点:
对一个变量取地址,可以通过编译,那就是左值;反之则为右值。左值可以作为右值,此时是用到的对象的值/内容,右值不能作为左值
这篇关于逻辑自洽地区分【左值与右值】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!