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…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
