C++基础知识 (引用)

news2024/11/18 5:50:28

⭐️ 往期相关文章

✨ 链接:C++基础知识(命名空间、输入输出、函数的缺省参数、函数重载)

⭐️ 引用

引用从语法的层面上讲:引用不是定义一个新的变量,而是给已存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间

🌠 例1

#include <iostream>
using namespace std;

int main() {

	int a = 10;
	int& ra = a;
	cout << ra << endl;

	ra = 20;
	cout << a << endl;

	return 0;
}

ps:  int& ra = a 这里的 raa 的引用(或者可以理解成 a 的别名),当 cout << ra 的时候相当于 cout << a ,当修改 ra = 20 的时候,a 的值也被修改了。

🌟 引用的特性:

  • 引用在定义时必须初始化
    • int& ra;   这种行为是 error
  • 一个变量可以存在多个引用
    • int num = 10;
    • int& q_num1 = num;
    • int& q_num2 = num;
  • 引用一旦引用一个实体,就不能再引用其他的实体
    • int num = 10;
    • int n = 20;
    • int q_num = num;
    • q_num = n    这里并不代表更换了引用。而是赋值:这里 q_num = n 是把 n 的值赋值给 q_numq_num 又是 num 的引用,就相当于 n 的值赋值给 num

🌟 引用的使用场景:

🌠 例2

#include <iostream>
using namespace std;

// 做参数
void swap(int& qa, int& qb) {
	int temp = qa;
	qa = qb;
	qb = temp;
}

int main() {

	int a = 10;
	int b = 20;
	cout << a << " " << b << endl;	// 10 20
	swap(a , b);
	cout << a << " " << b << endl;  // 20 10

	return 0;
}

ps: 当参数过大时,传值与传引用效率上会有一定的差距。


🌠 例3

#include <iostream>
using namespace std;

// 做返回值
int& func() {
	static int count = 0;
	cout << count << endl;
	count++;

	return count;
}

int main() {

	int res = func();
	res++;
	func();

	return 0;
}

在这里插入图片描述


ps: 首先这里 count 变量是被 static 修饰过的,所以并不是存在在栈区,而是静态区。return count 但是函数的返回是引用相当于返回了 count 的别名(这里可以理解为当函数栈帧销毁并且返回值的时候,会有一个临时变量来存储这个要返回的值,也就是可以理解成 int& temp = count 再把temp 引用返回),其实本质上就 count,所以当 count 的引用赋值给 res 就相当于把 count 赋值给 res 所以 res 的改变并不会影响静态区中的 count但是下面这种情况又不一样了。

🌠 例4

#include <iostream>
using namespace std;

int& func() {
	static int count = 0;
	cout << count << endl;
	count++;

	return count;
}

int main() {

	int& res = func();
	res++;
	func();

	return 0;
}

在这里插入图片描述


ps1: 这里返回值是被 int& res 接收的。而 res 相当于是静态区中 count 的别名,res++ 就相当于静态区中的 count++ , 所以第二次函数调用的时候 cout << count << endl 的时候是 2
ps2: 如果函数中的变量会被销毁则不可以使用引用返回,则必须使用传值返回。

🌠 例5

#include <iostream>
#include <assert.h>
using namespace std;

int& At(int * nums) {
	assert(nums);

	return nums[0];
}

int main() {

	int nums[10] = { 1 , 2 };

	At(nums) = 10;	// 直接可以修改返回值

	cout << nums[0] << endl;	// 10

	return 0;
}

ps: 使用返回引用的方式是可以直接修改返回值的,但是如果使用返回值的方式是不可以直接修改的,因为返回值会创建一个临时变量来保存,这个临时变量是常值变量不可被修改。

🌟 常引用:

🌠 例6

int main () {
	const int b = 20;
	//int& qb = b;	// error
	const int& qb = b;
}

ps: b 是被 const int 修饰的常量只有读的权限 而 qbint 类型的引用,这里是 error 的因为对于引用来说权限是不可以放大的。

🌠 例7

int main () {
	
	int c = 30;
	const int& qc = c; // 这样做是可以的 权限缩小
	
	const int& d = 20; // 这样也是可以的
}

ps: 权限是可以缩小的 c 是可读可写的,而它的引用也可以是只读的。

🌠 例8

int main () {
	int e = 50;
	//double& dd = e;	// error
	const double& dd = e;
}

ps: 当把整型给到浮点型时会发生自动类型转换,但是为什么整型 e 给不了 double 的引用呢?因为在自动类型转换的时候,首先并不会改变 e 的类型,而是在它们中间创建一个临时的变量e 给到这个临时变量在通过临时变量给到 dd。而这个临时变量是一个常值变量是不可以被修改的,所以这里本质上是发生权限放大的问题,如果原变量没有被 const 修饰,或者说不是一个常量,那么它的引用可以被 const 修饰也可以不被 const 修饰(引用的权限平移或者权限缩小),但是如果原变量是一个常量或者被 const 修饰,那么它的引用只能被 const 修饰,而不可以不被const修饰(权限放大)。


🌟 引用和指针的区别

在语法概念上引用就是一个别名,没有独立的空间,和引用的实体共用同一块空间。但是在底层实现上实际是有空间的,因为引用的是按照指针方式来实现的。

🌟 引用和指针的不同点:

  • 引用概念上是定义一个变量的别名,而指针是存储一个变量的地址。
  • 引用在定义时必须初始化,指针没有要求。
  • 引用在初始化时引用一个实体后,就不能引用其他的实体,而指针可以随意的更换指向。
  • 没有 NULL 引用,但是有 NULL 指针。
  • sizeof 中的含义不同:引用结果为引用类型的大小,但是指针始终是地址空间所占的字节个数(32位平台下4字节)。
  • 引用自增 1 即引用的实体增加 1 ,指针加 1 代表的是指针的指向后偏移一个类型的大小。
  • 有多级指针,没有多级引用。
  • 访问实体的方式不同,指针需要解引用操作符,而引用编译器会自己处理。
  • 引用相比指针更安全。

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

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

相关文章

黑马大数据学习笔记3-MapReduce配置和YARN部署以及基本命令

目录 部署说明MapReduce配置文件YARN配置文件分发配置文件集群启动命令开始启动YARN集群 查看YARN的WEB UI页面保存快照YARN集群的启停命令一键启动脚本单进程启停 提交MapReduce任务到YARN执行提交wordcount示例程序查看运行日志提交求圆周率示例程序 p41~43 https://www.bili…

无线温湿度信息中继器模块的组成和工作状态及编程与组网建议

在无线温湿度信息收集系统中&#xff0c;信息中继器模块是连接终端信息点与互联网的重要节点。本文将详细介绍该模块的组成和工作状态&#xff0c;并给出编程和组网的建议。 一、组成 该无线温湿度信息中继器模块由以下几个核心组成部分构成&#xff1a; STM32F103ZET6主控芯片…

17- C++ const和异常-5 (C++)

第六章 C对C的拓展2 6.1 const详解 6.1.1 const 修饰普通变量 被修饰的对象是只读的 const int a; //a的值是只读的 int const a; const int * p; 该语句表示指向整形常量的 指针&#xff0c;它指向的值不能修改。 int const * p; 该语句与b的含义相同&#xff0c;表…

adobe ps beta的使用方法

1、人物换发型。 1&#xff09;套索套选出来相关的头发。 2&#xff09;点击生成&#xff0c;输入“red hair” 按“生成”键。 2、人物换眼睛。 1&#xff09;套索套选出来相关的眼睛区域&#xff0c;大一点范围。 2&#xff09;点击生成&#xff0c;输入“blue eyes"…

【Golang 接口自动化03】 解析接口返回XML

目录 解析接口返回数据 定义结构体 解析函数&#xff1a; 测试 优化 资料获取方法 上一篇我们学习了怎么发送各种数据类型的http请求&#xff0c;这一篇我们来介绍怎么来解析接口返回的XML的数据。 解析接口返回数据 定义结构体 假设我们现在有一个接口返回的数据resp如…

分布式软件架构——内容分发网络

内容分发网络&#xff08;CDN&#xff0c;Content Distribution Network或Content Delivery Network&#xff09; 其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现…

【数据结构与算法】归并排序

归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是利用归并的思想实现的排序方法&#xff0c;该算法采用经典的分治&#xff08;divide-and-conquer&#xff09;策略&#xff08;分治法将问题分&#xff08;divide&#xff09;成一些小的问题然后递归求解&#xff0c;而…

LaTex语法(常用数学符号的语法和注意事项)

说明:[]括号表示把语法括起来&#xff0c;并不表示LaTex语法。 1. 求和符号(Σ) 这个符号的基本语法为&#xff1a;[\sum_{}^{}]。 符号有两种模式&#xff1a;内联数学模式(inside math mode)和显示数学模式(displayed math mode)。 内联数学模式&#xff1a;排版时使用各…

CAN通信的位定时与同步

位定时与同步 1.位时间 1.1相关基本概念 1&#xff09;系统时钟&#xff1a;记为 t c l k t_{clk} tclk​&#xff1b; 2&#xff09;CAN时钟周期&#xff1a;CAN时钟是由系统时钟分频而来的一个时间长度值&#xff0c;表示CAN控制器的工作时钟&#xff0c;实际上就是一个时…

【前端知识】React 基础巩固(四十二)——React Hooks的介绍

React 基础巩固(四十二)——React Hooks的介绍 一、为什么需要Hook? Hook 是 React 16.8 的新增特性&#xff0c;它可以让我们在不编写class的情况下使用state以及其他的React特性&#xff08;比如生命周期&#xff09;。 class组件 VS 函数式组件&#xff1a; class的优势…

C语言每日一题:9.《数据结构》链表的中间节点+链表的倒数第k个节点。

第一题&#xff1a; 题目链接&#xff1a; >思路一&#xff1a; 1.第一遍遍历链表&#xff0c;直到找到尾结束第一次遍历&#xff0c;遍历的过程中记录链表长度。定义长度为k。 2.确定中间是第几个节点&#xff0c;计算是k/21根据题目要求。 3.再一次去遍历我们的数组&…

iOS开发-格式化时间显示刚刚几分钟前几小时前等

iOS开发-格式化时间显示刚刚几分钟前几小时前等 在开发中经常遇到从服务端获取的时间戳&#xff0c;需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。 主要用到了NSCalendar、NSDateComponents这两个类 NSString *result nil;NSCalendarUnit components (NSC…

minGPT 代码详解(训练 GPT 模型执行两位数加法)

文章目录 1. MinGPT 项目简介2. 相关论文2.1 GPT-12.2 GPT-22.3 GPT-3 3. 代码详解3.1 项目结构3.2 GPT 模型代码详解3.2.1 Transformer block3.2.2 GPT 3.3 两位数加法实验3.3.1 数据集构造3.3.2 训练器3.3.3 模型参数设置3.3.4 训练过程 1. MinGPT 项目简介 MinGPT 是 GPT 模…

【Linux】关于Bad magic number in super-block 当尝试打开/dev/sda1 时找不到有效的文件系统超级块

每个区段与 superblock 的信息都可以使用 dumpe2fs 这个指令来查询的&#xff01; 不过可惜的是&#xff0c;我们的 CentOS 7 现在是以 xfs 为默认文件系统&#xff0c; 所以目前你的系统应该无法使用 dumpe2fs 去查询任何文件系统的。 因为目前两个版本系统的根目录使用的文…

Servlet文件的下载

第一种方法直接在前端使用超链接&#xff0c;也就是a标签 浏览器不能识别会直接下载&#xff08;像压缩文件不能直接下载&#xff09;&#xff0c;浏览器能识别&#xff0c;想要下载加一个download属性。download可以不写任何信息。 首先在web下建一个文件&#xff0c;放需要…

Vue 3:玩一下web前端技术(七)

前言 本章内容为VUE生命周期与相关技术讨论。 上一篇文章地址&#xff1a; Vue 3&#xff1a;玩一下web前端技术&#xff08;六&#xff09;_Lion King的博客-CSDN博客 下一篇文章地址&#xff1a; Vue 3&#xff1a;玩一下web前端技术&#xff08;八&#xff09;_Lion Ki…

9、测试Service组件和使用模拟组件辅助测试

测试Service组件和使用模拟组件辅助测试 测试Service组件 测试Service组件无需启动Web服务器&#xff0c;所以使用SpringBootTest(webEnvironment WebEnvironment.NONE)修饰测试用例类即可 &#xff08;用NONE表示不启动Web服务器&#xff09;。 Service组件其实就是一个普…

【002 操作系统】进程的状态及状态转换图?

一、进程的状态 1. 创建状态 2. 就绪状态 3. 运行状态 4. 阻塞状态 5. 终止状态 图源&#xff1a;进程、线程基础知识全家桶&#xff0c;30 张图一套带走_Linux_小林coding_InfoQ写作社区 NULL -> 创建状态&#xff1a;一个新进程被创建时的第一个状态&#xff1b; 创建状态…

python+django+mysql项目实践一(环境准备)

python项目实践 环境说明: Pycharm 开发环境 Django 前端 MySQL 数据库 Navicat 数据库管理 创建Pycharm项目 安装Django 在pycharm文件—设置进行安装 新建Django项目 注意项目创建目录 项目默认目录文件说明: __init__.py asgi.py 【异步接受网络…

Qt 5. QSerialPort串口收发

1. 代码 //ex2.cpp #include "ex2.h" #include "ui_ex2.h" #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo>int static cnt 0;Ex2::Ex2(QWidget *parent): QDialog(parent), ui(new Ui::Ex2) {ui->setupUi…