C++ 中的引用
文章目录
- C++ 引用的应用
- 1. 修改函数中传递的参数
- 2. 避免复制大型结构
- 3. for 循环中修改所有对象
- 4. for 循环中避免复制对象
- References vs Pointers
- 引用的限制
- 使用引用的优点
- 练习
- Quesition 1
- Question 2
- Question 3
- Question 4
- Question 5
- Question 6
如果一个变量被声明为引用,那它就成了一个已有变量的别名。一个变量可以通过在声明的时候加
&
而成为引用。
此外,还可以将引用变量定义为一种类型,它可以作为另一个变量的引用。&
用于表示变量或任何内存的地址。与引用变量关联的变量,既可以通过变量名访问,也可以通过与之关联的引用变量访问。
语法:
data_type &ref = variable;
例子:
// C++ Program to demonstrate
// use of references
#include <iostream>
using namespace std;int main()
{int x = 10;// ref is a reference to x.int& ref = x;// Value of x is now changed to 20ref = 20;cout << "x = " << x << '\n';// Value of x is now changed to 30x = 30;cout << "ref = " << ref << '\n';return 0;
}
输出:
x = 20
ref = 30
C++ 引用的应用
C++中的引用有很多的应用,如下是其中的一些:
- 修改函数中传递的参数;
- 避免复制大型结构;
- for 循环中修改所有对象;
- for 循环中避免复制对象;
1. 修改函数中传递的参数
如果一个函数接收到了一个变量的引用,它可以修改这个变量的值。如下程序变量是使用引用交换的。
// C++ Program to demonstrate
// Passing of references as parameters
#include <iostream>
using namespace std;// Function having parameters as
// references
void swap(int& first, int& second)
{int temp = first;first = second;second = temp;
}// Driver function
int main()
{// Variables declaredint a = 2, b = 3;// function calledswap(a, b);// changes can be seen// printing both variablescout << a << " " << b;return 0;
}
输出:
3 2
2. 避免复制大型结构
想象一下,一个函数必须接收一个大对象。如果我们没有使用引用来传递,那么它的一个新副本就会被创建,这回导致CPU时间和内存的浪费。可以使用引用来避免这种情况。
struct Student {string name;string address;int rollNo;
}// If we remove & in below function, a new
// copy of the student object is created.
// We use const to avoid accidental updates
// in the function as the purpose of the function
// is to print s only.
void print(const Student &s)
{cout << s.name << " " << s.address << " " << s.rollNo<< '\n';
}
3. for 循环中修改所有对象
我们可以在每个循环中使用引用来修改所有元素。
// C++ Program for changing the
// values of elements while traversing
// using references
#include <iostream>
#include <vector>using namespace std;// Driver code
int main()
{vector<int> vect{ 10, 20, 30, 40 };// We can modify elements if we// use referencefor (int& x : vect) {x = x + 5;}// Printing elementsfor (int x : vect) {cout << x << " ";}cout << '\n';return 0;
}
输出:
15 25 35 45
4. for 循环中避免复制对象
我们可以在每个循环中使用引用,以避免在对象很大时复制单个对象。
// C++ Program to use references
// For Each Loop to avoid the
// copy of objects
#include <iostream>
#include <vector>using namespace std;// Driver code
int main()
{// Declaring vectorvector<string> vect{ "geeksforgeeks practice","geeksforgeeks write","geeksforgeeks ide" };// We avoid copy of the whole string// object by using reference.for (const auto& x : vect) {cout << x << '\n';}return 0;
}
输出
geeksforgeeks practice
geeksforgeeks write
geeksforgeeks ide
References vs Pointers
引用和指针都可以用于在一个函数中修改另一个函数的局部变量。当作为参数传递给函数或从函数返回时,它们都可以用来避免复制大对象,从而提高效率。尽管有上述相似之处,引用和指针之间还是有以下区别。
- 指针可以被声明为
void
,但引用不可以int a = 10; void* aa = &a; // it is valid void& ar = a; // it is not valid
- 指针变量有n层/多层的间接,即单指针、双指针、三指针。然而,引用变量只有一个间接层次。下面的代码揭示了上述几点:
输出:// C++ Program to demonstrate // references and pointers #include <iostream> using namespace std;// Driver Code int main() {// simple or ordinary variable.int i = 10;// single pointerint* p = &i;// double pointerint** pt = &p;// triple pointerint*** ptr = &pt;// All the above pointers differ in the value they store// or point to.cout << "i = " << i << "\t"<< "p = " << p << "\t"<< "pt = " << pt << "\t"<< "ptr = " << ptr << '\n';// simple or ordinary variableint a = 5;int& S = a;int& S0 = S;int& S1 = S0;// All the references do not differ in their// values as they all refer to the same variable.cout << "a = " << a << "\t"<< "S = " << S << "\t"<< "S0 = " << S0 << "\t"<< "S1 = " << S1 << '\n';return 0; }
i = 10 p = 0x7ffecfe7c07c pt = 0x7ffecfe7c080 ptr = 0x7ffecfe7c088 a = 5 S = 5 S0 = 5 S1 = 5
- 引用变量不能更新;
- 引用变量是一个内部指针;
- 引用变量的声明前面有
&
符号(但不要将其读作“address of”)。
引用的限制
- 一个引用一旦被创建,它就不能再引用另一个对象;它不能被重置。这通常使用指针完成。
- 引用不能是NULL。指针经常用 NULL 来表示它没有指向任何有效的东西。
- 引用必须在声明的时候初始化,而指针没有该限制。
由于上面的限制,C++中的引用不能用于实现如链表、树等数据结构。Java 中,引用没有上述限制,可以用于实现所有的数据结构。Java不需要指针的主要原因是引用功能更强大。
使用引用的优点
- 更安全:由于引用必须初始化,所以像野指针这样的野引用不太可能存在。但仍然有可能存在不指向有效位置的引用(见下面练习中的第5和6题)
- 使用更方便:引用不需要解引用运算符来访问值。它们可以像普通变量一样使用。
&
运算符只有在声明的时候需要。此外,对象引用的成员可以通过点运算符(.
) 访问,而不像指针,需要箭头运算符(->
) 才能访问成员。
除了上述原因,还有一些地方如拷贝构造函数不能使用指针。在拷贝构造函数中必须使用引用传递实参,类似地,重载某些运算符如++
时必须使用引用。
练习
Quesition 1
#include <iostream>
using namespace std;int& fun()
{static int x = 10;return x;
}int main()
{fun() = 30;cout << fun();return 0;
}
输出:
30
Question 2
#include <iostream>
using namespace std;int fun(int& x) { return x; }int main()
{cout << fun(10);return 0;
}
输出:
./3337ee98-ae6e-4792-8128-7c879288221f.cpp: In function 'int main()':
./3337ee98-ae6e-4792-8128-7c879288221f.cpp:8:19: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'cout << fun(10);^
./3337ee98-ae6e-4792-8128-7c879288221f.cpp:4:5: note: in passing argument 1 of 'int fun(int&)'int fun(int& x) { return x; }
Question 3
#include <iostream>
using namespace std;void swap(char*& str1, char*& str2)
{char* temp = str1;str1 = str2;str2 = temp;
}int main()
{char* str1 = "GEEKS";char* str2 = "FOR GEEKS";swap(str1, str2);cout << "str1 is " << str1 << '\n';cout << "str2 is " << str2 << '\n';return 0;
}
输出:
str1 is FOR GEEKS
str2 is GEEKS
Question 4
#include <iostream>
using namespace std;int main()
{int x = 10;int* ptr = &x;int&* ptr1 = ptr;
}
输出:
./18074365-ebdc-4b13-81f2-cfc42bb4b035.cpp: In function 'int main()':
./18074365-ebdc-4b13-81f2-cfc42bb4b035.cpp:8:11: error: cannot declare pointer to 'int&'int&* ptr1 = ptr;
Question 5
#include <iostream>
using namespace std;int main()
{int* ptr = NULL;int& ref = *ptr;cout << ref << '\n';
}
输出:
timeout: the monitored command dumped core
/bin/bash: line 1: 34 Segmentation fault timeout 15s ./372da97e-346c-4594-990f-14edda1f5021 < 372da97e-346c-4594-990f-14edda1f5021.in
Question 6
#include <iostream>
using namespace std;int& fun()
{int x = 10;return x;
}int main()
{fun() = 30;cout << fun();return 0;
}
输出:
0
相关文章:
C++ 中的引用
文章目录 C 引用的应用1. 修改函数中传递的参数2. 避免复制大型结构3. for 循环中修改所有对象4. for 循环中避免复制对象 References vs Pointers引用的限制使用引用的优点练习Quesition 1Question 2Question 3Question 4Question 5Question 6 如果一个变量被声明为引用&#…...

MQ-Det: Multi-modal Queried Object Detection in the Wild
首个支持视觉和文本查询的开放集目标检测方法 NeurIPS2023 文章:https://arxiv.org/abs/2305.18980 代码:https://github.com/YifanXu74/MQ-Det 主框图 摘要 这篇文章提出了MQ-Det,一种高效的架构和预训练策略,它利用文本描述的…...

HarmonyOS应用开发初体验
9月25日华为秋季全场景新品发布会上,余承东宣布,全面启动鸿蒙原生应用,HarmonyOS NEXT开发者预览版将在2024年第一季度面向开发者开放。 最近鸿蒙开发可谓是火得一塌糊涂,各大培训平台都开设了鸿蒙开发课程。美团发布了鸿蒙高级工…...
《C++新经典设计模式》之第4章 策略模式
《C新经典设计模式》之第4章 策略模式 策略模式.cpp 策略模式.cpp #include <iostream> #include <memory> using namespace std;// if或switch分支不稳定,经常改动时,考虑引入算法独立到策略类中去实现// 依赖倒置原则 // 高层组件不应该依…...

【方法】PowerPoint“只读方式”如何取消?
PPT设置了以“只读方式”打开,可以保护文件无法编辑更改,那后续不需要保护了,或者想要编辑文件,要如何取消“只读方式”呢? 首先,我们要看看PPT设置的是哪种“只读方式”。 如果PPT设置的是无密码“只读方…...
MySQL数据库概念与实践
MySQL数据库概念与实践 1. 概念 MySQL是一种常用的关系型数据库管理系统,具有丰富的功能和广泛的应用。在本篇博客中,我们将介绍MySQL数据库的一些重要概念和相关知识。 存储引擎 存储引擎是MySQL数据库用于存储、更新和查询数据的技术实现方法。MyS…...

【ArcGIS Pro微课1000例】0052:基于SQL Server创建企业级地理数据库案例
文章目录 环境搭建创建企业级数据库连接企业级数据库环境搭建 ArcGIS:ArcGIS Pro 3.0.1Server.ecp:版本为10.7SQL Server:版本为SQL Server Developer 2019创建企业级数据库 企业级地理数据库的创建需要通过工具箱来实现。工具位于:数据管理工具→地理数据库管理→创建企业…...

深度学习——第3章 Python程序设计语言(3.7 matplotlib库)
3.7 matplotlib库 目录 1 matplotlib库简介 2 pyplot的plot函数 3 matplotlib基础绘图函数示例 数据可视化有助于深度理解数据。 本节介绍绘制图形的基本方法。 1. matplotlib库简介 matplotlib官网 1.1 matplotlib库概述 matplotlib是Python优秀的数据可视化第三方库&a…...

【数据分析实战】酒店行业华住集团门店分布与评分多维度分析
文章目录 1. 写在前面2. 数据集展示3. 多维度分析3.1 门店档次多元化:集团投资战略观察3.1.1 代码实现3.1.2 本人浅薄理解 3.2 门店分布:各省市分布概览3.2.1 代码实现3.2.2 本人浅薄理解 3.3 门店分级评分:服务水平的多维度观察3.3.1 代码实…...

近期Chrome浏览器 不知哪个版本升级后原先http强制跳转到https,导致服务端302强制跳转到http也没反应
关于Chrome更新http强制跳转到https解决方法 近期Chrome浏览器 不知哪个版本升级后原先http强制跳转到https,导致服务端302强制跳转到http也没反应一、F12检查加载的Response Headers中有没有Non-Authoritative-Reason二、找了资料后得到解决方案:三、找…...

【scikit-learn基础】--『数据加载』之样本生成器
除了内置的数据集,scikit-learn还提供了随机样本的生成器。通过这些生成器函数,可以生成具有特定特性和分布的随机数据集,以帮助进行机器学习算法的研究、测试和比较。 目前,scikit-learn库(v1.3.0版)中有2…...

基于 ESP32-S3 的 Walter 开发板
Walter 是一款基于 ESP32-S3 且拥有 5G LTE 连接功能的新型开源开发套件。 近日,比利时公司 DPTechnics BV 推出了一款基于乐鑫 ESP32-S3 且拥有 5G LTE 连接功能的新型开源开发套件。该套件即将在 Crowd Supply 平台上发布,您可以点击此处了解详情。 无…...

Gitlab+GitlabRunner搭建CICD自动化流水线将应用部署上Kubernetes
文章目录 安装Gitlab服务器准备安装版本安装依赖和暴露端口安装Gitlab修改Gitlab配置文件访问Gitlab 安装Gitlab Runner服务器准备安装版本安装依赖安装Gitlab Runner安装打包工具安装docker安装java17安装maven 注册Gitlab Runner 搭建自动化部署准备SpringBoot项目添加一个Co…...
待做-待补充-每个节点做事,时间,以及与角度的关系
文章目录 纲领1.是否可以通过遍历一遍二叉树得到答案2.是否可以通过两颗子树相同问题的答案推导出树的答案(形式为递归)无论哪种思维模式,都需要思考:单独一个二叉树节点,它需要做什么事情?需要在什么时候做 后序判断问题是否和子树相关&…...

液态二氧化碳储存罐远程无线监测系统
二氧化碳强化石油开采技术,须先深入了解石油储层的地质特征和二氧化碳的作用机制。现场有8辆二氧化碳罐装车,每辆罐车上有4台液态二氧化碳储罐,每台罐的尾部都装有一台西门子S7-200 smart PLC。在注入二氧化碳的过程中,中控室S7-1…...

kafka学习笔记--安装部署、简单操作
本文内容来自尚硅谷B站公开教学视频,仅做个人总结、学习、复习使用,任何对此文章的引用,应当说明源出处为尚硅谷,不得用于商业用途。 如有侵权、联系速删 视频教程链接:【尚硅谷】Kafka3.x教程(从入门到调优…...

UE4 材质实现Glitch效果
材质实现Glitch效果 UE4 材质实现Glitch效果预览1预览2 UE4 材质实现Glitch效果 预览1 添加材质函数: MF_RandomNoise 添加材质: 预览2 添加材质函数MF_CustomPanner: 添加材质函数:MF_Glitch 材质添加: 下面用…...

oracle实验2023-12-8--触发器
第十四周实验 【例】功能要求:增加一新表XS_1,表结构和表XS相同,用来存放从XS表中删除的记录。 分析: 1、创建表 xs_1 SQL> create table xs_1 as select * from xs; Table created SQL> truncate table xs_1; Table truncated题目&a…...
【Python百宝箱】贝叶斯统计的魅力:从PyMC3到ArviZ,探索数据背后的不确定性
标题:预测未来趋势的利器:深入贝叶斯统计和概率编程的世界 前言 贝叶斯统计和概率编程是一种强大的分析方法,可以帮助我们处理不确定性、建立灵活的模型以及进行参数估计和推断。本文将介绍几个常用的Python库,包括PyMC3、ArviZ…...

Knowledge Graph知识图谱—8. Web Ontology Language (OWL)
8. Web Ontology Language (OWL) 在RDFs不可能实现: Property cardinalities, Functional properties, Class disjointness, we cannot produce contradictions, circumvent the Non Unique Naming Assumption, circumvent the Open World Assumption 8.1 OWL Tr…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)
漏洞概述 漏洞名称:Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号:CVE-2023-25194 CVSS评分:8.8 影响版本:Apache Kafka 2.3.0 - 3.3.2 修复版本:≥ 3.4.0 漏洞类型:反序列化导致的远程代…...

简约商务通用宣传年终总结12套PPT模版分享
IOS风格企业宣传PPT模版,年终工作总结PPT模版,简约精致扁平化商务通用动画PPT模版,素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...