C++中的引用

2023-11-18

一、引用

引用不是定义一个新的变量,而是给一个已有的变量起一个别名。

类型  &引用变量名 = 已定义过的变量名;

注:1)一个变量可以有多个别名;

      2)引用必须初始化;

      3)引用只能在初始化时引用一次,不能在成为其他变量的别名。

#include <iostream>
using namespace std;
int main()
{
	int a = 13;
	//b,c,d都是a的别名,代表了同一个变量
	//一个变量可以有多个别名
	int& b = a;
	int& c = a;
	int& d = a;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
	cout << "d=" << d << endl;
	//引用只能被初始化一次,不能再次被初始化成为其它变量的别名
	int e = 20;
	b = e;    //这是一个赋值操作,把e的值赋给了b;并没有对b进行再次初始化,使b成为其它变量的别名
	//由于a,b,c,d指的是同一变量的别名,打印出来都是20
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "c=" << c << endl;
	cout << "d=" << d << endl;
	system("pause");
	return 0;
}


const引用:

#include <iostream>
using namespace std;
int main()
{       //常量具有常性,只有常引用才能引用常量
	const int a = 10;
	const int& b = a;

	//给一个常量建立引用时,也要加上const
	int c = 30;
	const int &d = c;
	system("pause");
	return 0;
}

上面建立的都是相同类型间的引用,那么不同类型之间可以使用引用吗?

二、引用的应用

1、引用做参数

相比于C语言中的传地址要方便的多,且效率更好。

void swap1(int *x, int *y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
void swap2(int& x, int& y)
{
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	int beg1 = GetTickCount();
	for (int i = 0; i < 100000000; i++)
	{
		swap1(&a, &b);        //传址
	}
	int end1 = GetTickCount();
	cout << "传指针:" << end1 - beg1 << endl;


	int beg2 = GetTickCount();
	for (int i = 0; i < 100000000; i++)
	{
		swap2(a, b);          //传引用
	}
	int end2 = GetTickCount();
	cout << "传引用:" << end2 - beg2 << endl;
	
	system("pause");
	return 0;
}

注:当我们不想在调用的函数内部改变该变量时,可以使用const引用。

2、引用做返回值

传值返回:用引用接收

int Add(int a, int b)
{
	//返回的是一个临时变量(匿名变量),该变量具有常性,用引用接收时要加上const,相当于给这个匿名变量起了一个别名
	return a + b;
}
int main()
{	
	const int& ret = Add(10, 20);
	cout << "10+20=" << ret << endl;
	system("pause");
	return 0;
}
传引用返回:
int& Add(int a, int b)
{
	int c = a + b;
	return c;              
}
int main()
{	
	int& ret = Add(10, 20);
	cout << "10+20=" << ret << endl;
	system("pause");
	return 0;
}

可以这样理解:


三、深入理解引用

先用汇编代码查看上面做引用返回的函数代用过程:(截取部分)

我们发现,在函数调用过程中,是把c的地址放到寄存器eax中,函数调用结束后,回到main函数的栈桢中,再从eax中的地址找到该地址的值。这时候,这个地址已经不再被变量c所使用,也就是说,从该地址取到的值不一定是我们想要的值。

所以,结论是:

1)不要返回一个临时变量的引用;

2)若出了作用域,该变量还存在,尽量返回该变量的引用。

对比返回指针的方式与返回引用的方式:


从汇编层讲,它们的实现是一样的;但从语法上讲,引用不用开辟新的空间,指针需要。

四、引用与指针的区别

1、引用只能在初始化时引用一次,之后就不能在改变为其它变量的引用(从一而终);而指针可以改变很多次。

2、引用必须指向有效的变量,指针可以为空。

3、sizeof(引用),结果为变量的大小;而sizeof(指针),结果为地址的大小。

4、自增自减含义不同。引用是该变量自增自减1;而指针是指针加或减类型的大小。

5、引用比指针更安全;指针比引用更灵活。






本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中的引用 的相关文章

  • 获取数组变量的地址是什么意思?

    今天我读到了一段让我很困惑的 C 代码片段 include
  • 为什么存在 async 关键字

    浏览 msdn 9 频道视频时 我发现以下未答复的评论 希望有人能解释一下 我不明白 async 关键字的意义 为什么不直接允许 任何时候方法返回任务时都会使用await关键字 就像迭代器一样 可以在任何返回 IEnumerable 的方法
  • 分段错误(核心转储)错误

    我的程序编译罚款 但在输入文件时出现 分段错误 核心转储 错误 我没有正确处理 ostream 吗 include
  • 在 C# 中生成 HMAC-SHA1

    我正在尝试使用 C 来使用 REST API API 创建者提供了以下用于 hmac 创建的伪代码 var key1 sha1 body var key2 key1 SECRET KEY var key3 sha1 key2 var sig
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • C# 正则表达式用于查找 中具有特定结尾的链接

    我需要一个正则表达式模式来查找字符串 带有 HTML 代码 中的链接 以获取文件结尾如 gif 或 png 的链接 示例字符串 a href site com folder picture png target blank picture
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • HttpWebRequest vs Webclient(特殊场景)

    我知道这个问题之前已经回答过thread https stackoverflow com questions 1694388 webclient vs httpwebrequest httpwebresponse 但我似乎找不到详细信息 在
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 默认析构函数做了多少事情

    C 类中的默认析构函数是否会自动删除代码中未显式分配的成员 例如 class C public C int arr 100 int main void C myC new C delete myC return 0 删除 myC 会自动释放
  • 分配器感知容器和propagate_on_container_swap

    The std allocator traits模板定义了一些常量 例如propagate on container copy move assign让其他容器知道它们是否应该在复制或移动操作期间复制第二个容器的分配器 我们还有propag
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • WPF。如何从另一个窗口隐藏/显示主窗口

    我有两个窗口 MainWindow 和 Login 显示登录的按钮位于主窗口 this Hide Login li new Login li Show 登录窗口上有一个检查密码的按钮 如果密码正确 我如何显示主窗口 将参数传递给 MainW
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • 类中不允许使用不完整类型,但类模板中允许使用不完整类型

    以下为无效代码 struct foo struct bar bar x error field x has incomplete type struct bar int value 42 int main return foo x valu
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L

随机推荐

  • 代码随想录算法训练营第一天

    704 二分查找 题目链接 力扣 二分法写代码时一般是写左闭右闭和左闭右开两种类型 左闭右闭 left right 左闭右开 left right 指右边不包含right这个值 int right size 两大问题 while left
  • 全新的刷脸支付开辟一条全新发展之路

    数字化和刷脸支付的强强联合给众多商家带去希望和惊喜 崭新的2021年 这个惊喜仍然在继续 数字化经营刷脸支付 如何为创业者带去商机 2020年 是刷脸支付发展的黄金时期 它曾因为疫情跌落到谷底 却也因为疫情再次飞上云端 重拾自信 在行业巨头
  • form 校验多个表单

    有的时候 表单需要拆开多个 这时候就需要校验多个表单
  • Qt 学习之路:线程和 QObject

    前面两个章节我们从事件循环和线程类库两个角度阐述有关线程的问题 本章我们将深入线程间得交互 探讨线程和QObject之间的关系 在某种程度上 这才是多线程编程真正需要注意的问题 现在我们已经讨论过事件循环 我们说 每一个 Qt 应用程序至少
  • c# winform对数据库进行增删改查操作

    开发工具 sqlserver2012 visoual code 2017 打开sqlserver2012 创建一个表 表结构如下 然后打开VS2017 文件 新建 项目 Windows窗体应用 这里我就在工具箱拉取了三个button和一个显
  • VS Code+Anaconda(国内源)配置python

    一 Anaconda的介绍 为何使用 优点 二 Anaconda下载和安装 三 VS Code下载及安装 四 Anaconda更换国内源 原因及操作方法 操作方法 具体操作方法 记得看上边优秀博客 五 TensorFlow环境 配置原因及优
  • equals底层

    Equals底层实现 这篇文章有抄两个博主的东西 请不要介意 学习最重要 主要怕你们什么时候删帖看不到 谢谢 在基础类型中都重写了equals方法 但是Object中的equals的方法如果不重写就没有意义 因为源代码中equals直接用
  • Equals和HashMap的重写

    一 首先 老铁们应该先了解API中的HashCode和equals解释 1 如果两个对象相同 即用equals比较返回true 那么它们的hashCode值一定要相同 2 如果两个对象的hashCode相同 它们并不一定相同 即用equal
  • 光敏传感器简介

    光敏传感器 1 简介 光敏传感器是最常见的传感器之一 它的种类繁多 主要有 光电管 光电倍增管 光敏电阻 光敏三极管 太阳能电池 红外线传感器 紫外线传感器 光纤式光电传感器 色彩传感器 CCD和CMOS图像传感器等 光传感器是目前产量最多
  • Spring boot按日切分nohup.out日志文件的方法

    过大的日志文件维护起来存在诸多问题 所以最好是能够按日或按大小切分日志文件 下面给大家带来了Spring boot按日切分spring boot的nohup out日志文件的方法 方法如下 1 安装cronolog 2 执行以下命令启动应用
  • 完美解决umi+ProLayout 部分菜单动态的问题

    项目中用到这个框架 当然是很好用且方便的 但是实际使用的时候发现项目中限制了一些自定义内容 踩了几个坑 记录一下 动态菜单调用接口异步 页面上显示空白 解决方案 将方法放在getInitialState中查询 存在initialState里
  • 线性回归算法--拟合正弦函数

    目录 步骤 代码实现 本博客参考书籍 scikit learn机器学习 常用算法原理及编程实战 本博客源码地址 码云 步骤 生成200个在 2 2
  • Jeesite权限处理,权限分配,根据不同的用户展示不同的信息,按钮权限等

    jeesite关于权限这方面的记录或者文章很少 看官方文档又看不懂 自己的业务又需要进行权限处理 怎么办 当然问大佬了 我就记录下我的解决办法 给jeesite权限方面的文章做点贡献 我先说下我的业务逻辑 我需要实现不同公司的人登陆后台 只
  • 相似矩阵反推标签

    Background 有监督的多模态检索 supervised multi modal retrieval 中 常用 label 构造相似矩阵 S 样本集 X x i
  • vue中组件之间传递数组

    let InFo JSON stringify arr localStorage setItem array InFo 通过 JSON stringify 将数组解析成字符串 let Info JSON parse localStorage
  • gcc -c -o编译过程

    gcc编译 分步处理 一 预处理 二 编译 三 汇编 四 链接 一步到位 多模块编译 一次性编译 独立编译 C源文件到可执行文件共经历了4个过程 在使用GCC编译程序时 编译过程可以被细分为四个阶段 包括预处理 编译 汇编 链接 分步处理
  • 分析排序算法的时间复杂度和空间复杂度

    1 冒泡排序 时间复杂度 O n 2 空间复杂度 O 1 冒泡排序需要进行n 1趟冒泡 每一趟需要比较n i次 最坏情况下需要交换n 1次 故时间复杂度为O n 2 冒泡排序的空间复杂度是O 1 因为只需要使用一个临时变量即可 2 选择排序
  • 【C++】动态内存管理和泛型编程

    需要云服务器等云产品来学习Linux的同学可以移步 gt 腾讯云 lt gt 阿里云 lt gt 华为云 lt 官网 轻量型云服务器低至112元 年 新用户首次下单享超低折扣 目录 一 C C 内存区域划分 二 常见变量存储区域 三 new
  • 程序员必知,招聘黑话大全!

    大家周末愉快 今天分享 IT 行业一些常见的招聘术语 准备参加面试的朋友一定要知道 Base base 有两层含义 对于薪资来说 base 即为你的基本薪资 假设你的薪资组成为 20k 16 签字费 股票 这个 20k 则为你的薪资 bas
  • C++中的引用

    一 引用 引用不是定义一个新的变量 而是给一个已有的变量起一个别名 类型 引用变量名 已定义过的变量名 注 1 一个变量可以有多个别名 2 引用必须初始化 3 引用只能在初始化时引用一次 不能在成为其他变量的别名 include