【C++入门】什么是引用

目录

一、引用概念

二、引用特性

三、常引用

四、使用场景

1. 做参数

2. 做返回值

五、传值,传引用效率比较

六、引用和指针的区别


一、引用概念

        引用不是新定义一个变量,而是给已存在变量取一个别名,编译器不会为引用变量开辟内存空间,它和引用的变量共用一块内存空间

比如:鲁迅,原名“周树人“,笔名“鲁迅”,小说里又称自己为”迅哥“。

类型&引用变量名(对象名)= 引用实体

#include<iostream>
using namespace std;void test_1()
{int a = 1;int& ra = a;cout << a << endl << ra << endl;cout << &a << endl << &ra << endl;
}int main()
{test_1();return 0;
}

输出结果为:

表示 a 与 ra 的值一样,址一样。

注意:引用变量必须和引用实体同种类型的。下面这种引用就不行:

二、引用特性

1. 引用在定义时必须初始化

2. 一个变量可以有多个引用

3. 引用一旦引用一个实体,再不能引用其他实体

#include<iostream>
using namespace std;void test_1()
{int a = 1;//int& ra;//会报错int& ra = a;int& rra = a;int b = 2;cout << a << endl << ra << endl << rra << endl;cout << &a << endl << &ra << endl << &rra << endl;
}int main()
{test_1();return 0;
}

 输出结果为:

表示 a,ra,rra的值与址都相同。

三、常引用

#include<iostream>
using namespace std;void test_1()
{int a = 1;//int& ra = a;//会报错,a为常量const double& ra = a;a = 2;//a可修改//ra = 2;//ra不可修改//int& b = 10;//会报错,b为常量const int &b = 2;double d = 12.34;const int& rd = d;
}int main()
{test_1();return 0;
}

通过上述代码可以看到,当常引用:const int& a = b 时,b可修改,由于是a是b的引用,b修改时a也会随之修改,但是不可对a直接修改。

四、使用场景

1. 做参数

void swap(int& a,int& b)
{int tmp = a;a = b;b = tmp;
}int main()
{int a = 1, b = 2;swap(a, b);return 0;
}

2. 做返回值

int& count()
{static int a = 1;a++;return a;
}

引用做返回值的时候,在一些情况下会出现问题。下面举一个例子来说明一下,且看以下代码:

#include<iostream>
using namespace std;int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3,4);cout << "Add(1, 2) is :" << ret << endl;return 0;
}

此时输出的结果是多少呢?我们来看一下:

结果为7,诶?ret 明明就是Add(1,2)的返回值的引用啊,应该是3才对,为什么结果会是Add(3,4)的返回值呢?这个时候就要用函数栈帧的知识来解释了。

下面画了张分析图:

由这张图仔细分析可知,第一次 Add 操作后,返回值所在的空间就被释放掉了,但是空间本身还在,此时ret所引用的还是这一块空间,但是在第二次 Add 操作的时候,这块空间被重复利用了,空间内变量的值发生了改变,此时 ret 引用的值就变成了7了。

所以:将引用作为返回值时要注意空间释放的问题,要考虑这块空间是否还是原来的那块空间。

五、传值,传引用效率比较

        以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

六、引用和指针的区别

        在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用一块空间。

#include<iostream>
using namespace std;
int main()
{int a = 10;int& ra = a;cout << "&a = " << &a << endl;cout << "&ra = " << &ra << endl;return 0;
}

输出结果为:

        但在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

#include<iostream>
using namespace std;
int main()
{int a = 10;int& ra = a;ra = 20;int* pa = &a;*pa = 20;return 0;
}

引用和指针的汇编代码对比:

引用和指针的不同点:

1. 引用概念上定义一个变量的别名,指针存储一个变量地址。

2. 引用在定义时必须初始化,指针没有要求

3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以再任何时候指向任何一个同类型实体。

4. 没有NULL引用,但有NULL指针。

5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数

6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

7. 有多级指针,但是没有多级引用

8.访问实体方式不同,指针需要显式解引用引用编译器自己处理

9. 引用比指针使用起来相对更安全

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

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

相关文章

C++ 函数对象 详解

目录 &#x1f914;函数对象&#xff1a; &#x1f914;本质&#xff1a; &#x1f914;特点&#xff1a; 代码示例&#xff1a; 运行结果&#xff1a; &#x1f914; 内置函数对象&#xff1a; 1.算数仿函数 代码示例&#xff1a; 运行结果&#xff1a; 2.关系仿函数 …

华为OD机试真题B卷 Java 实现【字符串分隔】,附详细解题思路

一、题目描述 输入一个字符串&#xff0c;请按长度为8拆分每个输入字符串并进行输出&#xff0c;长度不是8整数倍的字符串请在后面补数字0&#xff0c;空字符串不处理。 二、输入描述 连续输入字符串(每个字符串长度小于等于100)。 三、输出描述 依次输出所有分割后的长度…

如何查看Steam的17位Id

方法/步骤 1、点击左上角Stream中的设置 2、 进入后点击“界面”&#xff0c;勾选“当可用时显示steam URL 地址栏”。 3、最后点击“查看个人资料”后17位即为ID。

steam注册模拟注册

代替手动模拟注册steam帐号

账号的注册

给账号注册&#xff0c;主要是给数据库中添加一个账号类数据&#xff0c;如图是以userName为用户名和password为密码的数据列表&#xff1a; 给用户和密码添加新的数据就是一个基础的账号注册&#xff0c;下面是页面的主要内容代码样式&#xff1a; 给相应的元素赋予name值&…

Steam注册遇到CAPTCHA问题,一直注册不了,一个简单的注册办法

这个问题一直解决不了 后来我就用了V.P.eN翻墙在Google Chrome上粘贴进入网址再注册就巨快 我自己用的一个很简洁&#xff0c;好用免费的VPeN叫白鲸 V.P.eN下载网址&#xff1a;https://www.bjch110.com/?mid1003 下载安装都很简单 然后白鲸显示连接上后&#xff0c;就打开Goo…

怎样注册邮箱账号?

邮箱账号的注册可以按照以下2种途径&#xff1a; 一、Web端注册 1、网页端搜索&#xff1a;http://163.net&#xff0c;点击“立即注册” 2、4个邮箱套餐&#xff0c;可以根据自己的使用情况进行选择 3、填写申请的邮箱账号&输入密码&#xff0c;手机号码&#xff0c;完…

Unity账号注册

Unity账号注册 文章目录 Unity账号注册 先找到Unity官网 看图: ##基本信息填入 &#xff1a; 密码格式&#xff1a; 用户名错误提示 用户名已存在: 用户名无效&#xff08;可能含有特殊字符或特殊字符串&#xff09;: ##验证信息 账号注册有两种验证方法&#xff1a;…

Steam注册到交易

Steam注册到交易 Steam注册到交易 Steam注册到交易Steam注册注册邮箱下载steam和网易UU加速注册Steam 手机令牌绑定 Steam注册 注册邮箱 163网易免费邮–中文邮箱第一品牌 申请一个你喜欢的邮箱名字和你的手机号就注册好你的邮箱啦。 下载steam和网易UU加速 大概是在这里…

IMX6ULL裸机篇之I2C相关寄存器

一. I2C实验 I2C时钟选择与传输速率 1. IMX6ULL的 I2C频率标准模式 100kbit/S&#xff0c;快速模式为 400Kbit/S 2. 时钟源选择 perclk_clk_rootipg_clk_root66MHz&#xff08;由之前的时钟实验章节可以知道是 66MHz&#xff09;。 二. I2C 寄存器配置 I2Cx_IFDR寄存器&…

使用docker和minio实现对象存储

文章目录 使用docker和minio实现对象存储什么是minio安装minio使用minio 使用docker和minio实现对象存储 什么是minio ​ Minio是一个开源的分布式文件存储系统&#xff0c;它基于 Golang 编写,虽然轻量&#xff0c;却拥有着不错的高性能&#xff0c;可以将图片、视频、音乐、…

k 折交叉验证

1. 原理步骤&#xff1a; 第一步&#xff0c;不重复抽样将原始数据随机分为 k 份。第二步&#xff0c;每一次挑选其中 1 份作为测试集&#xff0c;剩余 k-1 份作为训练集用于模型训练。第三步&#xff0c;重复第二步 k 次&#xff0c;这样每个子集都有一次机会作为测试集&…

R语言k折交叉验证

“机器学习中需要把数据分为训练集和测试集&#xff0c;因此如何划分训练集和测试集就成为影响模型效果的重要因素。最近我们被要求撰写关于k折交叉验证的研究报告&#xff0c;包括一些图形和统计输出。本文介绍一种常用的划分最优训练集和测试集的方法——k折交叉验证。” k折…

Keras入门(八)K折交叉验证

在文章Keras入门&#xff08;一&#xff09;搭建深度神经网络&#xff08;DNN&#xff09;解决多分类问题中&#xff0c;笔者介绍了如何搭建DNN模型来解决IRIS数据集的多分类问题。   本文将在此基础上介绍如何在Keras中实现K折交叉验证。 什么是K折交叉验证&#xff1f; K折…

基于R语言进行K折交叉验证

我们在建立数据模型后通常希望在外部数据验证模型的检验能力。然而当没有外部数据可以验证的时候&#xff0c;交叉验证也不失为一种方法。交叉验验证&#xff08;交叉验证&#xff0c;&#xff23;&#xff36;&#xff09;则是一种评估模型泛化能力的方法&#xff0c;广泛应用…

【机器学习】Stacking与K折交叉验证

其他机器学习系列文章见于专题&#xff1a;机器学习进阶之路——学习笔记整理&#xff0c;欢迎大家关注。 1. Stacking定义 Stacking并不是简单地对个体学习器的结果做简单逻辑处理&#xff0c;而是先从初始数据集训练出初级学习器&#xff0c;将初级学习器的输出当成特征&…

K折交叉验证实现

K折交叉验证 k折交叉验证是划分数据集的一种方式&#xff0c;特别适合少量数据集 在原始数据中划分k份&#xff0c;取1份作为测试集&#xff0c;k-1份作为训练集 最后算出平均性能值 以MINIST数据为例子 python from tensorflow import keras import numpy as np import mat…

简述k折交叉验证法

1、以二分类任务为例&#xff0c;假定数据集D包含1000个样本&#xff0c;将其划分为训练集S和测试集T&#xff0c;其中S包含800个样本&#xff0c; T包含200个样本&#xff0c;用S进行训练后&#xff0c;如果模型在T上有50个样本分类错误&#xff0c;那么模型的正确率为75% 。 …

root 密码破解(rd.break)

在Linux系统中&#xff0c;忘记root密码时&#xff0c;可以用此方法进行暴力修改root密码 示例&#xff1a; 设置一个新的记不住的密码 $ echo cnakdnvf | passwd --stdin root $ poweroff 1.启动此虚拟机&#xff0c;选中以下行&#xff0c;并按 【 e 】进入内核编辑页面 …

k折交叉验证

一般情况将K折交叉验证用于模型调优&#xff0c;找到使得模型泛化性能最优的超参值。&#xff0c;找到后&#xff0c;在全部训练集上重新训练模型&#xff0c;并使用独立测试集对模型性能做出最终评价。 K折交叉验证使用了无重复抽样技术的好处&#xff1a;每次迭代过程中每个样…