C/C++陷阱——临时变量的产生和特性

news2024/11/23 0:26:07

C/C++陷阱——临时变量的产生和特性

在学习C++常引用时,有这样一段代码引起了我的注意:

int a = 1;
double& b = a;

当我编译这段代码时,竟然报错了:

在这里插入图片描述

按理来说,初始化引用时不能涉及权限的放大(如用const int初始化int&),但是这里只是权限的平移,为什么会错误呢?

我们可以看到报错信息里有这样一句话:非常量限定,这指的又是什么呢?

这就是本次要讨论的重点——临时变量的产生和特性

在C和C++中,临时变量通常指的是临时创建并存储数据的变量,它们在表达式求值或函数调用中起到临时存储值的作用。这些临时变量通常是由编译器自动生成的,无需程序员显式声明或管理

临时变量的产生

临时变量主要在下面这两种情况下产生:

  1. 类型转换

当需要将一个数据类型转换为另一个数据类型时,通常会生成临时变量来保存转换后的值

例如:

int a = 10;
double b = a;

我们都知道,将整型变量a赋值给双精度浮点型变量b时,涉及到了隐式类型转换,但我们可能大多数都忽略了这个过程中就产生了一个临时变量来存储转换后的值,最后变量b接收的就是这个临时变量。因为只有这样,我们才能在类型转换的过程中确保变量a的数据是完整的、合规的、安全的。

又例如:

int a = 1;
int* pt = (int*)a;

我们总不能说,将整型变量a强制转换为整型指针后,整型变量a就变成指针了吧。

  1. 函数调用

当一个函数返回一个值时,通常会生成临时变量来存储函数的返回结果。这个临时变量可以被赋给其他变量或用于进一步的操作。

int Add(int a, int b)
{
	int sum = a + b;

	return sum;
}

int main()
{
	int ret = Add(1, 2);

	return 0;
}

Add函数就是一个简单的两数相加的函数。那么小伙伴觉得这个函数的返回值是什么?是变量sum吗?当然不是,应该清楚局部变量出了其所在函数的作用域后就会被销毁,因此当Add函数被调用完后,sum所代表的值就是一个随机数了。因此实际上,编译器一般都会生成一个临时变量来存储函数返回的结果,最后ret接受的也是这个临时变量。

除了上面两种情况外,还有其他的一些情况也会有临时变量的产生,大家了解即可:

  1. 表达式求值:当需要计算一个表达式,特别是包含多个操作数和操作符的复杂表达式时,编程语言通常会生成临时变量来保存中间结果。
  2. 中间计算:在执行复杂计算时,可以使用临时变量来存储中间计算结果,以避免重复计算相同的值。
  3. 循环迭代:在循环结构中,迭代计数器通常被视为临时变量,因为它们在每次迭代中都会被更新。
  4. 条件语句:在条件语句中,如果需要根据条件执行不同的操作,临时变量可能会用于存储条件的结果或中间值。
  5. 数组和容器操作:在对数组、向量、列表等数据结构进行操作时,可能会生成临时变量来存储临时元素或中间结果。
  6. 错误处理:在处理异常或错误时,临时变量可以用于存储错误信息或状态。

临时变量的常性

临时变量有一个很重要的特性:常量性

这一个特性确保了临时变量是不可以被修改,这其中也就包括了权限不能被放大

例如:

int Add(int a, int b)
{
	int sum = a + b;

	return sum;
}

int main()
{
	Add(1, 2)++;

	return 0;
}

就会报错:

这里解释一下左值和右值的概念:

  1. 左值(L-value):左值是可以出现在赋值操作符(例如=)的一侧的表达式,表示一个可以被赋值的内存位置通常是一个变量。左值表示一个标识符或一个引用,它指向内存中的某个位置。例如,如果你有一个变量x,那么x就是一个左值,因为你可以将一个值赋给它,如x = 10。
  2. 右值(R-value):右值是一个表达式的结果值,它可以出现在赋值操作符的右侧。右值通常是计算的结果,它可以是常数、临时变量或函数的返回值。例如,如果你有一个表达式x + y,它的结果是一个右值,因为它代表一个值,但你不能将一个值赋给它。

报错信息显示,函数的返回值不是一个左值,也就是说返回的临时变量是不可被修改的。这也从侧面反映了临时变量的常性。

除此之外,临时变量还有其他一些特性,大家仅作了解即可:

  1. 短暂寿命:临时变量通常在其创建点的作用域内存在,一旦超出该作用域,它们就会被销毁。这使它们成为一种短暂的存储设备。
  2. 匿名:通常,临时变量没有显式的名称,因为它们是在表达式求值或函数调用期间自动创建的。它们只是在内部存储中的值。
  3. 用于中间计算:临时变量通常用于存储中间计算结果或值的转换。它们帮助管理复杂的表达式,确保正确的计算顺序。
  4. 可被编译器优化:现代编译器通常会进行优化,以最小化临时变量的使用,以提高性能。它们可以消除不必要的临时变量,以减少内存开销。
  5. 值语义:临时变量通常采用值语义,这意味着它们存储的是具体的值,而不是引用或指向其他变量。这有助于避免共享状态和副作用。
  6. 用于函数返回:在函数返回值的情况下,临时变量通常用于存储函数的结果,以便将其传递给调用方。
  7. 隐式创建和销毁:编程语言和编译器通常会自动创建和销毁临时变量,程序员无需显式管理它们的生命周期。
  8. 类型与原始值相关:临时变量的类型通常与它们所包含的值的类型相关,以确保类型的一致性。

总结

通过对临时变量的了解,我们就可以解释最开始提到的问题了:

int a = 1;
double& b = a;

当用整形变量a初始化浮点型引用b时,涉及到了隐式类型转换,那么中间就会产生一个double临时变量来临时存储a的值,但由于临时变量具有常性,其权限不能被放大,因此double& b = a;这句就是错误的。我们应该改为**const double& b = a;确保权限不变**。


本篇完。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1098358.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑群晖自动调整cpu模式

DS918 黑群晖好像是不支持cpu动态频率,导致cpu一直在最高频率运行,导致功耗比较高,但是某些版本的系统不支持设置为自动根据cpu负载动态调整频率,自己写了个脚本,支持自动根据cpu使用率调整cpu模式 脚本下载链接如下 …

朴实无华的三天每日一题

leetcode八分钟补完三天的每日一题哈哈哈哈 主打一个求同存异 import java.util.Arrays;class Solution {public int singleNumber(int[] nums) {Arrays.sort(nums);int ans 0;for (int i 0; i < nums.length; ) {try {if (nums[i] nums[i 1]) {i 2;} else {ans nums…

讲解 CSS 过渡和动画 — transition/animation (很全面)

前言 由于用户越来越注重 Web应用 的使用体验&#xff0c;随之而来的是 Web应用 需要提供了更加完善的 Web 动画 效果来实现以平滑的状态贯穿于用户的整个使用过程中。现在&#xff0c;这已经是司空见惯了&#xff0c;用户潜意识是希望可以获得更快的反馈响应和更友好的用户界…

2023年全球新能源云母材料市场发展展望分析:储能云母市场规模快速增长[图]

云母作为电气设备的基础材料&#xff0c;下游应用领域涉及高温冶炼、电力等传统行业&#xff0c;并在近几年逐步扩展到新能源汽车、电化学储能等新兴行业。2022年&#xff0c;全球云母材料市场规模保持稳定增长至180.0亿元&#xff0c;期间年复合增长率约为13.2%。预计未来&…

React TreeSelect设置默认展开项的方法

需要实现TreeSelect组件的onTreeExpand、treeExpandedKeys方法。 代码样例如下&#xff1a; 1.TreeSelect标签部分 render() {const {codeselect} this.props;const {treeExpandedKeys} this.state ................<TreeSelectshowSearch{false}dropdownStyle{{ maxHei…

day06_面向对象基础

今日内容 1 复习 2 面向对象编程介绍 3 面向对象 类,属性,方法 ,创建对象,使用对象内存关系 一、复习 周一: jdk,配置环境变量,idea,HelloWorld 变量,基本数据类型 周二: 运算符,if,if-else 周三: if-elseif-elseif-else,循环(while,dowhile,for) 周四: 方法设计(参数,返回值),…

vue3学习(六)--- 插槽slot

文章目录 匿名插槽具名插槽作用域插槽渲染作用域 动态插槽 插槽就是&#xff1a;子组件中的提供给父组件使用的一个占位符&#xff0c;用<slot></slot> 表示&#xff0c;父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&#xff0c;填充的内…

C++项目实战——基于多设计模式下的同步异步日志系统-⑫-日志宏全局接口设计(代理模式)

文章目录 专栏导读日志宏&全局接口设计全局接口测试项目目录结构整理示例代码拓展示例代码 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计划导师&#xff0c;阿里云专家博主&#xff0c;C…

安全典型配置(三)使用ACL禁止特定用户上网案例

【微|信|公|众|号&#xff1a;厦门微思网络】 安全典型配置&#xff08;一&#xff09;使用ACL限制FTP访问权限案例_厦门微思网络的博客-CSDN博客本例中配置的本地用户登录密码方式为irreversible-cipher&#xff0c;表示对用户密码采用不可逆算法进行加密&#xff0c;非法用…

VulnHub lazysysadmin

一、信息收集 1.nmap扫描开发端口 开放了&#xff1a;22、80、445 访问80端口&#xff0c;没有发现什么有价值的信息 2.扫描共享文件 enum4linux--扫描共享文件 使用&#xff1a; enum4linux 192.168.103.182windows访问共享文件 \\192.168.103.182\文件夹名称信息收集&…

YOLO目标检测——抽烟吸烟数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;公共场所监管、健康风险评估、戒烟干预数据集说明&#xff1a;YOLO目标检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富。使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yolo(txt)三…

mask-R-CNN

前言 代码 论文 # Mask-rcnn 算法在 torch vision 中有直接实现&#xff0c;可以直接引用使用在自己的工作中。 import torchvision model torchvision.models.detection.maskrcnn_resnet50_fpn(weightsMaskRCNN_ResNet50_FPN_Weights.DEFAULT)Mask R-CNN&#xff08;Mask R…

uni-app实现拍照功能

直接些这样的组件代码 <template><view><button click"takePhoto">拍照</button><image :src"photoUrl" v-if"photoUrl" mode"aspectFit"></image></view> </template><script&g…

Web(3)网络扫描与window,Linux命令

NMAP各种选项的使用 三种情况修改IP地址总结&#xff1a; 1.为漏洞环境配ip地址 注&#xff1a;1.打开metasploitable后&#xff0c;用mafadmin/msfadmin登录后&#xff0c;重新设置密码&#xff0c;su root登录; 为此创建一个ip地址&#xff0c;命令&#xff1a;ifconfig et…

centos 7.9离线安装wget

1.下载安装包 登录到wget官网上下载最新的wget的rpm安装包到本地 http://mirrors.163.com/centos/7/os/x86_64/Packages/ 2.上传安装包到服务器 3.安装 rpm -ivh wget-1.14-18.el7_6.1.x86_64.rpm 4.查看版本 wget -V

智能测径仪数据采集系统 棒材产线智能化提升方向必备

棒材企业通过学习先进技术和进行技术交流&#xff0c;形成了建设智能化生产线的共识&#xff0c;然而棒材生产线目前存在数据采集效率低、物料跟踪难、质量管控弱、成品质量差、库区混乱、成本居高等问题。通过增加钢坯表面检测、钢坯无头焊接、控轧控冷、自动测径、高速冷床、…

C++DAY46

myWidget::myWidget(QWidget *parent): QWidget(parent) {this->resize(1280,720);this->setWindowTitle("300英雄");this->setWindowIcon(QIcon("D:/BaiduNetdiskDownload/孤独摇滚图标/1.png"));this->setStyleSheet("background-color…

AI电销机器人好不好用关键是什么?

影响AI电销机器人是否好用的两个因素分别是&#xff0c;识别系统以及线路。 有很多电销企业都想找一个好用的AI电销机器人&#xff0c;可是什么样的机器人才是好用的机器人呢?有哪些因素会影响AI电销机器人好不好用呢? 添加图片注释&#xff0c;不超过 140 字&#xff08;可选…

内存访问与栈

内存访问与栈 1 内存分段2 DS和[address]3 mov、add、sub指令形式4 栈4.1 入栈与出栈4.2 SS与SP4.3 空栈4.4 栈顶超界4.5 push、pop指令 5 小结 本文属于《 X86指令基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 内存分段 在x86程序执行时&#xff0c;内存会被分段&am…

微信小程序的框架

目录 一、视图层 1. WXML 数据绑定 列表渲染 条件渲染 模板 2. WXSS 尺寸单位 样式导入 内联样式 选择器 3. WXS事件 二、逻辑层 1. 页面生命周期 2.跳转 1. 一级跳一级 2. 一级跳二级 3. 二级跳二级 4. 二级跳一级 总结 带给我们的收获 一、视图层 1. …