当前位置: 首页 > news >正文

【C/C++】理解C和C++中的左值和右值

原文和完整内容:https://blog.csdn.net/xuwqiang1994/article/details/79924310

 

简单定义


lvalue(locator value)代表一个在内存中占有确定位置的对象(换句话说就是有一个地址)。
rvalue  rvalue是不在内存中占有确定位置的表达式。

左值:有址值

右值:无址值

基本例子

int var;
var = 4;

赋值运算符要求一个lvalue作为它的左操作数,var是一个左值,因为它是一个占确定内存空间的对象。另外下面的代码是无效的:

4 = var;        //ERROR!
(var + 10) = 4; //ERROR!

常量4和表达式var+1都不是lvalue(它们是rvalue)。因为都是表达式的临时结果,没有确定的内存空间(它们只是计算的周期驻留在临时的寄存器中)。因此给它们赋值没有语意-这里没有地方给它们赋值。

int foo() { return 2; }

int main()
{
    foo() = 2;
    return 0;
}

 foo返回一个临时的rvalue。尝试给它赋值,foo()=2,是一个错误;编译器期待在赋值运算符的左部分看到一个lvalue。
不是所有的对函数调用结果赋值都是无效的。比如,C++的引用(reference)让这成为可能:

int globalvar = 20;

int& foo()
{
    return globalvar;
}

int main()
{
    foo() = 10;
    return 0;
}

这里foo返回一个引用,这是一个左值,所以它可以被赋值。C++从函数中返回左值的能力对于实现一些重载运算符时很重要的。一个普遍的例子是在类中为实现某种查找访问而重载中括号运算符 []。std::map可以这样做。

std::map<int, float> mymap;
mymap[10]=5.6;

给 mymap[10] 赋值是合法的因为非const的重载运算符 std::map::operator[] 返回一个可以被赋值的引用。

‘&’ 符号在C++中扮演了另一个重要角色-它允许定义 引用类型。这被称为“左值引用”。非const左值引用不能被赋右值,因为这将要求一个无效的右值到左值的转换:

std::string& sref = std::string(); //错误:无效的初始化,用一个右值类型‘std::string’初始化非const引用类型‘std::string&’
  • 常量左值引用可以被赋右值。因为它们是常量,不能通过引用被修改,因此修改一个右值没问题。这使得C++中接受常量引用作为函数形参成为可能,这避免了一些不必要的临时对象的拷贝和构造。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【MQTT】MQTT C语言客户端实现/ MQTT嵌入式客户端
  • 【VS】VS工程设置(包含目录、库目录、附加包含目录、附加库目录、附加依赖项)等...
  • 【linux】最小测试工程miniTest
  • 【VS】判断dll/lib是32/64位|查看lib是导入库/静态库的方法
  • 【C++】C++写后端程序
  • 【C++】C++ 知识点100题
  • 【架构】傻瓜都能看懂的高并发量服务器架构
  • 【mySQL】MySQL数据库知识整理
  • 【mySQL】Mysql InnoDB 共享表空间和独立表空间 区别和优缺点
  • 【算法】程序的时间复杂度计算
  • 【算法】CRC、MD5、SHA1区别
  • 【libevent 】libevent 多线程实现高并发
  • 【redis】hiredis-vip (hiredis封装成支持cluster的api)
  • 【知识】IPxx防水等级 说明
  • 【安全】哈希(hash)算法可以防止数据被篡改的原理是什么
  • Java 网络编程(2):UDP 的使用
  • Java多线程(4):使用线程池执行定时任务
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • miaov-React 最佳入门
  • Python 反序列化安全问题(二)
  • python学习笔记 - ThreadLocal
  • Python语法速览与机器学习开发环境搭建
  • React Transition Group -- Transition 组件
  • SOFAMosn配置模型
  • SpingCloudBus整合RabbitMQ
  • tab.js分享及浏览器兼容性问题汇总
  • 给第三方使用接口的 URL 签名实现
  • 开发基于以太坊智能合约的DApp
  • 如何胜任知名企业的商业数据分析师?
  • 小程序button引导用户授权
  • 以太坊客户端Geth命令参数详解
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 原生 js 实现移动端 Touch 滑动反弹
  • 智能合约开发环境搭建及Hello World合约
  • ionic异常记录
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • #include
  • (C语言)fread与fwrite详解
  • (九)c52学习之旅-定时器
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)JPA - JQPL 实现增删改查
  • (图)IntelliTrace Tools 跟踪云端程序
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • **《Linux/Unix系统编程手册》读书笔记24章**
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET CORE 第一节 创建基本的 asp.net core
  • .NET 通过系统影子账户实现权限维持
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .NET大文件上传知识整理
  • .Net组件程序设计之线程、并发管理(一)