本文转自:https://www.cnblogs.com/relaxease/p/16027916.html
C++的左值和右值
摘要
C++语言中的左值和右值是困扰我的知识点,今天将学习到的知识点整理一下,以理清概念。本文首先介绍了左值、右值的一般分类和概念,包括广义左值,将亡值和纯右值,然后介绍了我对左值和右值的理解:将左值理解成水桶,将右值理解成水,最后介绍了左值引用和对常量的左值引用。
表达式值的分类
本文说的左值(lvalue)和右值(rvalue),其中的“值”就是表达式(expression)的值。C++17标准定义了表达式值的分类,其主要分为3类:
- 广义左值(glvalue):在程序员编程时,程序员可以取地址的东西(对象、函数)。举例:变量、函数等。
- 纯右值(prvalue):在程序员编程时,程序员不可以取地址的东西。举例:字面值常量。
- 将亡值(xvalue):本身可以被程序员取地址,但是马上就不能被取地址了的东西。
这三种类别和左右值的关系图:
三种类别和左右值的关系图
总结一下,可以这么理解左值和右值:左值,就是可以取地址的东西;右值就是不可以取地址的东西。
左右值的理解
我把左值理解成水桶,右值理解成水。这样我感觉比较好记忆和理解。比如:
int x; //x左值,理解成一个水桶
x = 10; // 10是右值,理解成水
int *p = &x; // 可以对水桶取地址,找到放水桶的地址
&10; // 编译错误,水没有位置,不能取地址
int y = x; // 把x水桶里的水复制一份到y水桶。
又如:
int f() {
int x = 10; // x是一个水桶
return x; //但是要被返回了,也就是这个水桶要被“销毁”。
}
int main() {
f() = 10; //编译错误,水桶已被销毁,不能盛水了
return 0;
}
左值引用
左值引用,就是在水桶上贴上了一个标签,这个标签代表了水桶(其实变量名字也可以理解成水桶上的标签)。
比如:
int a = 10;
int &b = a; //贴上标签
注意到常量的左值引用可以绑定到字面值常量上,也就是说以下代码是正确的:
const int & c = 10; //编译正确,但是“10”是右值,理解成水,c是左值引用,理解成标签。
但是如果把左值引用理解成在水桶上贴标签的话,以上代码就与这个理解产生冲突了。毕竟“标签”不能贴到“水”上。
其实,编译器会创建一个隐藏的变量来让引用c
绑定到10
上。比如:
const int & c = 10;
//会被翻译成这样:
int __internal_unique_name = 10;
const int& c = __internal_unique_name;
也就是说,编译器会创建一个左值(理解成“水桶”)来存储10(理解成“水”),然后再让引用绑定到该左值上(理解成在水桶上贴标签)。
总结
本文介绍了对左值和右值的理解。如果有什么错误,希望读者可以批评指正!
参考
- [1]微软C++文档
- [2]Internal Pointers的博客
标签:10,右值,水桶,左值,C++,int,理解 来源: https://www.cnblogs.com/liangzige/p/16460388.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。