初识C++ (三)

news2024/12/20 15:34:44

初识C++ 三

  • 引用
    • 一. 引用的概念
      • 代码演示
    • 二. 引用特性
      • 1. 引用在定义时必须要初始化
      • 2. 一个引用可以有多个实体
      • 3. 引用一旦引用一个实体,再不能引用其他实体
    • 三. 使用场景
      • 1. 做参数
      • 2. 做返回值
        • 内存销毁后空间还在吗?
        • 内存销毁后我们还能访问嘛?
      • 结论
      • 优点
    • 四. 传值传引用的效率比较
    • 五. 引用与重载函数
    • 六. 常引用
      • 右值为常数问题
  • 总结

在这里插入图片描述
如果有什么想要去做的事情就立马去做
全部做完了收收心 继续投入学习!

引用

一. 引用的概念

“引用(Reference)是 C++ 相对于C语言的又一个扩充。引用可以看做是数据的一个别名,通过这个别名和原来的名字都能够找到这份数据。

具体是什么意思呢?

我们这里来举个例子

比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。

那你叫铁牛 他会答应你

你叫黑旋风 他也会答应你

在这里插入图片描述

代码演示

我们下面来写一段代码试试

int main()
{
	int a = 10;
	int& b = a;
	return 0;
}

这段代码是什么意思呢?

我们假设这个a是李逵

那么这个b就是黑旋风的意思了!

我们打印这两个变量的地址来看看

在这里插入图片描述
它们的地址一样的 都是李逵!

在这里插入图片描述

注意:引用类型必须和引用实体是同种类型的

比如说像我们这样子

在这里插入图片描述
这里就是一个错误代码

二. 引用特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体

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

在这里插入图片描述
这里如果不初始化就会报错 不用多讲了

2. 一个引用可以有多个实体

我们有代码如下

int main()
{
	int a = 10;
	int& b = a;
	int& c = a;


	//char& c = a; 不能改变类型

	printf("%p\n", &a);
	printf("%p\n", &b);
	printf("%p\n", &c);
	return 0;
}

在这里插入图片描述

这里它们的地址全部都一模一样 就可以说明它们都是一个地址的别名了

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

这句话是什么意思呢?

就拿我们的c来说

他已经引用了a了 还能不能引用其他变量呢

在这里插入图片描述

我们可以发现 它们的地址是没有变化的 那么

    c=d;

这一步代码 到底改变了什么呢?

我们画图来看看

在这里插入图片描述

我们来验证下我们的理论正确不正确

在这里插入图片描述
这里就可以发现 a b c的值全部都变成20了

三. 使用场景

1 . 做参数
2 . 做返回值

1. 做参数

我们来看下面的代码

要求: 交换两个变量的值

void swap(int x, int y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}

可是上面这段代码真的能够交换两个变量的值嘛?

看过我的这两篇博客的同学应该知道 答案是 不能

函数栈帧(上)

函数栈帧(下)

为什么呢?

因为x y只是我们要交换的函数的临时拷贝

交换它们的值并不会对要交换的值有什么影响

那么结合我们今天学到的知识

同学们有没有想到一种巧妙的解法呢?

没错! 就是引用传参

我们写出下面这样子的代码

void swap(int& x, int& y)
{
	int tmp = 0;
	tmp = x;
	x = y;
	y = tmp;
}

将它们的别名传进去 就可以啦

思考题:
我们都知道 在单链表头插尾插的时候 为了防止头指针为空的情况 我们就需要传递一个二级指针进去
这样子很麻烦
那么使用我们的引用机制如何修改它呢?

答案就是! 将指针的别名(引用)作为参数传递进去 那么修改引用参数是不是就可以了?

如果不能理解的话这样子

李逵吃饱了是不是就等于黑旋风吃饱了?

我们之后再来看以下代码

#include <time.h>
struct A { int a[10000]; };

void TestFunc1(A a) {}
void TestFunc2(A& a) {}

void TestRefAndValue()
{
	A a;
	int begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1(a);
	int end1 = clock();

	int begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2(a);
	int end2 = clock();


	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}

int main()
{
	TestRefAndValue();

	return 0;
}

在这里插入图片描述
我们可以发现使用两个函数运行的时间竟然相差很多!

这是为什么呢?

这里就设计到一个传值和传引用的区别(大家类比下传值和传址)
传值需要将整个a拷贝一份
而我们使用引用的话不会拷贝 时间就差在这里

2. 做返回值

还是一样 我们先来看这么两段代码

int& Count()
{
   static int n = 0;
   n++;
   // ...
   return n; }
int Count()
{
	int n = 0;
	n++;
	// ...
	return n;
}

在这里插入图片描述
这两段代码的返回值都是1

但是它们返回的方式可不同

我们先来看第二个代码

int Count()
{
	int n = 0;
	n++;
	// ...
	return n;
}

当我们调用count()这个函数的时候 它会开辟一个新的内存空间在这里临时空间里面设置一个n变量

将n的值加加

到了这一步的时候

return n;

将n的值放到寄存器里面返回

再来看看你第一个代码

int& Count()
{
   static int n = 0;
   n++;
   // ...
   return n; }

前面的过程几乎一样

注意! 这时候它的返回参数是 int&

也就是说 它直接是把n返回过来了!

不知道大家能不能看出来区别

一个是返回到寄存器中 一个值直接返回n的值

那么这里就引出一个很危险的操作!

int& Count()
{
   int n = 0;
   n++;
   // ...
   return n; }

我们将static去掉 这个时候n彻底变成局部变量了!

这个时候我们打印一下试试看
在这里插入图片描述

咦?

竟然还是1 难道说局部全局变量没有影响嘛?

当然不是!!!

我们再来写出以下代码

void test()
{
	cout << "hello world" << endl;
}

int main()
{
	int& ret = Count();
	cout << ret << endl;
	test();
	cout << ret << endl;

	return 0;
}

在这里插入图片描述
我们发现! 竟然ret变成随机值了!

这是为什么呢?

因为我们实际上得到的ret是n的别名 但是呢在函数结束调用之后所有的参数就被销毁了(这其中也包括n) 当我们运行另外的一个函数来调用栈空间的时候 有可能就将n地址的内容改变了 所以说造成了这个现象

那么这里就引用出两个问题

内存销毁后空间还在吗?

空间还在 但是已经不属于我们了

内存销毁后我们还能访问嘛?

可以访问 但是里面的数据的读写我们都不能确定

结论

1 出了函数作用域,返回变量不存在了,不能用引用返回,因为引用返回的结果是未定义的。
2 出了函数作用域,返回变量存在,才能使用引用返回。

优点

可以修改返回值

比如说

在这里插入图片描述
如果说我们使用 int 来接受ret的话那么只能够每次都给ret赋值了

四. 传值传引用的效率比较

参考做参数 使用场景1中的举例

五. 引用与重载函数

我们来看以下代码
在这里插入图片描述

这两个函数显然是构成重载函数的

但是我们却不建议这么写

因为很有可能造成歧义

比如说你打出下面的代码

test(10);

那么你究竟是想调用谁呢?

六. 常引用

这里牢记一个概念就好
我们引用一个变量的时候所具有的权限只能小于等于该变量

例如

int main()
{
	// a具有读写能力
	int a = 10;
	int& b = a;
	// 可以
	const int& b = a;
	// 权限缩小 可以

	const int c = 20;
	int& d = 20;
	// 权限放大 不可以
	const int& d = 20;
	// 权限相同 可以




	return 0;
}

在这里插入图片描述

右值为常数问题

常数是不可以被改变的 所以说没有写权限

其实不是不能引用而是权限不匹配

如果一定要可以用以下方式写代码

    const int& a = 10;
	// 读写权限匹配
	cout << a << endl;

在这里插入图片描述

总结

在这里插入图片描述

以上就是关于c++引用博主一些浅薄的理解啦
如果出现错误希望大佬们指正!
阿尼亚 哇酷哇酷!

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

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

相关文章

论文写作——ICASSP论文写作及投稿

记录 ICASSP2023 写作投稿过程。小白如何写好并投稿自己的第一篇英文论文&#xff1f;投稿会议时&#xff08;以 ICASSP2023 为例&#xff09;有哪些需要关注的信息以及注意事项&#xff1f;论文写作必备软件有哪些&#xff1f;论文书写关注点有哪些&#xff1f;论文格式与排版…

【Node.JS 】http的概念及作用

往期文章 【Node.JS 练习】时钟案例 【Node.JS 】path路径模块 【Node.JS 练习】考试成绩整理 【Node.JS】buffer类缓冲区 【Node.JS】事件的绑定与触发 【Node.JS】写入文件内容 【Node.JS】读取文件内容 什么是http模块 在网络节点中&#xff0c;负责消费资源的电脑&…

【C语言】C语言文件操作详解(一)

前言 本章主要讨论的是数据文件&#xff0c;如何使用C语言对数据文件进行输入输出数据的操作&#xff0c;以及文件顺序读写涉及的库函数详解 目录前言1.为什么使用文件2.什么是文件2.1程序文件2.2数据文件2.3文件名3.文件的打开和关闭3.1文件指针3.2文件的打开3.3文件的关闭3.…

初识JAVA

文章目录初识 java 的 main 方法main 方法示例运行Java程序注释基本规则注释规范标识符关键字初识 java 的 main 方法 main 方法示例 public class test {public static void main(String[] args) {System.out.println("hello world!");} }如果我们学的C语言&#…

DASCTF X GFCTF 2022十月挑战赛 Writeup

文章目录WEBEasyPOPMISC滴滴图ez_xxdpoi&#xff1f;qoi&#xff01;easy_dotsdockermiscWEB EasyPOP Fast Destruct优先一步__wakeup()执行析构函数 从一道题看fast_destruct fine::__invoke() <- sorry::__get() <- secret_code::show() <- secret_code::__call…

使用 MySQL 日志 - Part 1

在软件应用程序中&#xff0c;日志文件会记录系统中执行的操作以及执行操作的人员。如果出现意外情况&#xff0c;无论是安全漏洞、系统崩溃还是性能迟缓&#xff0c;日志文件都可以成为管理员的得力助手。MySQL 就有几个不同的日志文件&#xff0c;可以帮助你找出 MySQL 服务器…

Excel多条件计数——COUNTIFS【获奖情况统计】

问题描述 当前&#xff0c;我们需要对表格中的获奖情况进行统计 奖励级别&#xff1a;院级、校级、国家级、国际级奖励内容&#xff1a;特等奖、一等奖、二等奖、三等奖、优胜奖 功能要求 对所有奖励级别进行统计根据级别&#xff0c;计算内容数量 当有人的选项内容如下时 …

MySQL之SQL的执行流程

MySQL之SQL的执行流程MySQL架构连接层服务层存储引擎连接查看连接连接与线程连接超时最大连接会话与全局查询缓存语法解析和预处理词法解析语法解析预处理查询优化器优化器查询执行计划存储引擎存储引擎概述常用存储引擎MyISAMInnoDBMEMORY存储引擎的选择执行引擎MySQL架构 从…

DBMS 中的 2 层架构与 3 层架构

有多种方法可以获取存储在数据库管理系统中的数据。根据其结构对 DBMS 的体系结构进行了分类。 DBMS 架构概述 理解 2-tier 和 3-tier 架构是一个相当重要的话题&#xff0c;不仅对于学术或寻找好工作&#xff0c;而且对于与技术相关的一般意识也是如此。 2-tier simple表示两…

【每日渗透笔记】覆盖漏洞+修改隐藏数据实战尝试

目录 一、特点&#xff1a; 1.1、特征&#xff1a; 1.2、知识&#xff1a; 1.3、注册的功能点&#xff1a; 目前&#xff1a; 问题&#xff1a; 二、分析数据包 2.1、修改数据处 三、换思路 一、特点&#xff1a; 1.1、特征&#xff1a; 存在注册的功能点 1.2、知识&a…

资本狂欢过后 Aptos如何顶住旧日光环?

10月27日&#xff0c;Aptos Autumn主网上线一周后&#xff0c;其浏览器数据显示&#xff0c;该Layer1网络的交易总量为1432万笔&#xff0c;TPS为10.65&#xff0c;原生Token APT总供应量约为10.02亿&#xff0c;质押数量约为8.23亿枚&#xff0c;活跃节点数量102个。 低TPS、高…

AIR780E使用AT连接TCP收发数据

最近各种技术群都被合宙9.9的开发板刷屏了&#xff0c;笔者成功的第一时间拼团成功&#xff0c;已经作为前两百人收到开发板了&#xff0c;因为官方的二次开发固件还没出&#xff0c;就先玩一下传统的AT开发。 文中各种文档和资料均可以在air780e.cn网站找到。 本文将介绍如何…

99208-90-9_炔基-棕榈酸_Alkynyl Palmitic Acid 可进行定制

一、产品简介----Product introduction&#xff1a; 货号&#xff1a;Y-CL-0063 CAS&#xff1a;99208-90-9 中文名&#xff1a; 15-十六碳炔酸&#xff0c;炔基-棕榈酸 英文名&#xff1a;Alkynyl Palmitic Acid/hexadec-15-ynoic acid 结构式&#xff08;Structural&#xff…

深度学习:GoogLeNet核心思想详细讲解(原创)

深度学习&#xff1a;GoogLeNet核心思想详细讲解想法来源时代局限性稀疏运算特性稀疏矩阵稀疏运算并行计算结合稀疏与并行Inception blockGoogLeNetAverage pooling辅助分类器训练方法(Training Method)超参数设置模型集成训练阶段预测阶段基于GoogLeNet的服装分类&#xff08;…

WordPress 6.1新功能 (特性和截图)

WordPress 6.1 Beta 于几天前发布&#xff0c;预计将于 2022 年 11 月 1 日发布。这将是 2022 年的最后一个主要版本&#xff0c;将带来许多新功能和改进。 我们一直在密切监视开发并在我们的测试站点上尝试新功能。 在本文中&#xff0c;我们将通过功能和屏幕截图让您先睹为快…

基于javaweb的医院管理系统(java+springboot+mybatis+vue+mysql)

基于javaweb的医院管理系统(javaspringbootmybatisvuemysql) 运行环境 Java≥8、MySQL≥5.7、Node.js≥10 开发工具 后端&#xff1a;eclipse/idea/myeclipse/sts等均可配置运行 前端&#xff1a;WebStorm/VSCode/HBuilderX等均可 适用 课程设计&#xff0c;大作业&…

对于一个即将上线的网站,如何测试

web应用&#xff1a;也叫做网站&#xff0c;相对于客户端应用来说&#xff0c;web应用无需单独安装&#xff0c;在浏览器上即可使用其功能。 web应用的主要开发流程如下&#xff1a; 在网站开发的整个流程中&#xff0c;测试验收是上线发布前的最后一个环节&#xff0c;测试是…

Linux环境下安装Jenkins

首先安装Jenkins之前&#xff0c;linux中必须安装好了JDK和Maven&#xff0c;如果还没有安装过&#xff0c;下面准备好安装教程 Linux环境安装JDK: https://www.cnblogs.com/xuliangxing/p/7066913.html Linux环境安装Maven: https://blog.csdn.net/qq_35868412/article/detail…

【数据库04】中级开发需要掌握哪些SQL进阶玩法

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;相当硬核&#xff0c;黑皮书《数据库系统概念》读书笔记&#xff0c;讲解&#xff1a; 1.数据库系统的基本概念(数据…

Unicode云对象对接代码Demo

实现点击按钮&#xff0c;获取云对象返回内容&#xff0c;例下图 新建云对象-co1 index.obj.js代码 // 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj // jsdoc语法提示教程&#xff1a;https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129 mo…