C++ 左值和右值
2022/7/9 14:22:11
本文主要是介绍C++ 左值和右值,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文转自: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的博客
这篇关于C++ 左值和右值的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享