C++ 引用详解(引用的特点,引用与指针的区别,引用的其他使用)

article/2025/9/20 20:05:22

目录

  • 引用
  • 一.引入</font>
  • 二.C++中较为麻烦的运算符</font>
  • 三.引用的定义</font>
  • 四.引用的特点
  • 五.对比指针与引用
  • 六.引用与指针的区别(重点
    • 1.语法层面的区别
    • 2.汇编层面的区别
  • 七.引用的其他使用

引用

一.引入

在生活中,我们可能也会给一些同学起外号,以“张磊”同学为例,我们可以叫他“张三石”,当我们叫到这个外号的时候就会自然而然的想到“张磊”同学,”张三石”就是张磊的别名,而引用也可以这样简单理解:在语法层面上,引用就是取别名

二.C++中较为麻烦的运算符

C++中的 * 和 & 有多重含义,在不同的使用条件下有不同的意思:
*

int *p = &a;   /1.指针
a = a * b;     /2.乘法
*p = 100;      /3.指向

&

int c = a&b;    /1.位运算 转换为二进制
int *p = &a;    /2.取地址
int  a = 100;
int & ar = a;   /3.引用

三.引用的定义

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

格式如下

类型 & 引用变量名(对象名) = 引用实体
注意这里的空格是可选的,即

  • &符号与前后均可以有一个空格;如下:int & ra=a;
  • &符号与类型挨着,如下:int& ra=a;
  • &符号与引用名称挨着,如下:int &ra=a;

int main()
{
int a =100; \\定义变量名
int b = a;\\将a的值赋给变量
int &c = a;\\引用 将c作为a的别名 c11中成为左值引用
return 0;
}

在这里就是相当于一个实体取了两个名字分别为a和c,并且在这个空间中不开辟新的空间。
在这里插入图片描述

四.引用的特点

  1. 定义引用时必须给初始化
  2. 没有空引用
  3. 没有所谓的二级引用
  4. 一个变量可以有多个引用(就相当于一个变量有好几个别名,这是可以的)

说明:
int main()
{
int a = 10;
int& b = a;
int& x;
int& y = NULL;
int&& c = a;
}
在这里插入图片描述
总而言之:
引用本身是一个变量,但是这个变量又仅仅是另外一个变量一个别名,它不占用内存空间,它不是指针哦!仅仅是一个别名!

五.对比指针与引用

我们以交换函数为例
使用指针交换两个整型值:

int my _swap (int*ap, int*bp)
{assert(ap != NULL && bp != NULL);int tmp = *ap;*ap = *bp;*bp = *ap;
}
int main()
{int x = 10, y = 20;my_swap{&x,&y);cout<< "x = " << x << " y = " << y << endl;return 0;
}

使用引用交换两个指针:

void my_swap (int& a,int& b)
{int tmp = a;a = b;b = tmp;
}
int main ()
{int x = 10, y = 20;my_swap(x,y) ;cout << " x = " << x<< " y = " << y << endl;return 0;
}

形参为指针时:第一句话一定要断言,必须判断空不空;并且在使用指针的时候 我们需要注意:是否为 野指针, 空指针 ,失效指针
当我们使用引用时,不存在NULL引用,不需要判空,比指针更加安全

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
所以:能不使用指针就尽量不要使用指针!
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

六.引用与指针的区别(重点

1.语法层面的区别

  1. 从语法规则上讲,指针变量存储某个实例(变量或对象)的地址;
    引用是某个实例的别名。
  2. 程序为指针变量分配内存区域;而不为引用分配内存区域。
int main()
{int a = 10;int* ip = &a;int& b = a;  \\b是a的别名 并没有分配新的空间
}
  1. 解引用是指针使用时要在前加“*”;引用可以直接使用。
int main()
{int a = 10;int* ip = &a;int& b = a;  *ip = 100//对于指针使用加“*”b = 200//引用不需要“*”}
  1. 指针变量的值可以发生改变,存储不同实例的地址;
    引用在定义时就被初始化,之后无法改变(不能是其他实例的引用)。
int main()
{int a = 10,b = 20;int* ip = &a;ip = &b ;int& c = a;c = b;   //b的值给c实则是把b的值给a,将a的值改为20
}
  1. 指针变量的值可以为空(NULL,nullptr);没有空引用。
  2. 指针变量作为形参时需要测试它的合法性(判空NULL);
    引用不需要判空。
  3. 对指针变量使用"sizeof"得到的是指针变量的大小;
    对引用变量使用"sizeof"得到的是变量的大小。
int main()
{double dx = 10;double* dp = &dx;double& a = dx; printf("sizeof(dp):%d\n", sizeof(dp));printf("sizeof(a):%d", sizeof(a));
}

运行结果:
在这里插入图片描述

  1. 理论上指针的级数没有限制;但引用只有一级。
    即不存在引用的引用,但可以有指针的指针。

  2. ++引用与++指针的效果不一样。

例如就++操作而言:

int main()
(int ar[5] = { 1,2,34,5 };int* ip = ar; //数组首元素地址int& b = ar[O]; //数组首元素的别名叫b++ip;  //由0下标的地址指向1下标的地址++b;  //由0下标指向1下标
}

在这里插入图片描述

  1. 对引用的操作直接反应到所引用的实体(变量或对象)。
    对指针变量的操作,会使指针变量指向下一个实体(变量或对象)的地址;而不是改变所指实体(变量或对象)的内容。
int main()
(int ar[5] = { 1,2,34,5 };int* ip = ar; //数组首元素地址int& b = ar[O]; //数组首元素的别名叫b++(*ip); //值由1>>2 (*ip)++; //所有表达式结束后 进行++ //有括号 先取ip的值与*结合 然后++为所指之物的++int x = *ip++;//没有括号 先将ip的值取出 与*结合 把所指之物取出(此时已与*结合完) 然后将ip取出进行++ ++后的值回写给ip 将值存储到x中//通过()提高了优先级
}
  1. 不可以对函数中的局部变量或对象以引用或指针方式返回。

    当变量的生存期不受函数的影响时就可以返回地址

2.汇编层面的区别

汇编层面来讲引用就是一个指针,但是引用并不是一个普通的指针是指针的语法槽,也可以看作是常性的指针 。

int main()
{int a = 10;int* ip = &a;int& x = a;*ip = 100;x = 200;
}

在这里插入图片描述

七.引用的其他使用

  1. 常引用:

常引用实际上是一种万能引用既可以引用普通变量 ,常量,也可以引用字面常量

(1)引用普通变量

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

对于这块报错问题:是因为c是不可修改的
在这里插入图片描述
(2)引用常量

int main()
{int a = 10;const int b =20;int& x = a;int& y = b;  //error 不安全const int& y = b; //okconst int& z =10; //okreturn 0;
}

在这里插入图片描述
(3)引用字面常量

引用字面常量时,分两步走,首先定义一个临时量 去引用临时量 不是引用真实的字面常量10。

int main()
{int a = 10;const int& z =10; //ok//int tmp =10;//const int &z = tmp;return 0;
}
  1. 数组引用

在引用数组时,必须知道数组的大小

int main()
{int a = 10;int b = 10;int ar[5] = { 1,2,3,4,5 };int& x = ar[0];  //okint(&x)[5] = ar; //ok   没有[5]无法编译通过return 0;
}
  1. 指针引用

引用既然就是一个变量,那我同样也可以给指针变量取一个别名

int main()
{int a = 100;int *p = &a;int * &rp = p;cout << a << endl;cout << *p << endl;cout << *rp << endl; //这里为什么要将*放在前面,因为p的类型是 int * 作为一个整体哦!!cout << p << endl;cout << rp << endl;getchar();return 0;
}
/*
100
100
100
012FF84C
012FF84C
*/

我们发现这里的指针变量p和它的引用(别名)rp是完全一样的。但是由于引用的目的跟指针的目的是类似的,所以一般不需要对指针再起别名了。


http://chatgpt.dhexx.cn/article/GknSVuEx.shtml

相关文章

Zipkin和Sleuth

“sleuth的作用是在系统中自动埋点并把数据发送给zipkin,zipkin的作用是存储这些数据并展现。” 说白了 sleuth就是为了Zipkin服务的 看了一圈 总结一下 就是微服务的链路追踪 我们看这个延迟的时间可以判断哪个服务出现了问题 进而排查出问题 简单说&#xff1a;假如服务 …

spring-cloud-sleuth分布服务跟踪式

why: 1,微服务架构微服务增多&#xff0c;一个客户端请求形成一个复杂的分布式服务调用链路&#xff0c;如果任何一个服务延迟过高或错误&#xff0c;都会引起请求失败。 how&#xff1a; 先引入了example&#xff1a; https://github.com/spring-cloud/spring-cloud-sleuth 1…

笔记:Sleuth 的底层逻辑

Sleuth 是通过打入到 Log 中的“卧底”来串联前后日志的。你集成了 Sleuth 组件之后&#xff0c; 它会向你的日志中打入三个“特殊标记”&#xff0c;其中一个标记你应该已经清楚了&#xff0c;那便是 Trace ID。剩下的两个标记分别是 Span ID 和 Parent Span ID&#xff0c;…

sleuth介绍

spring Cloud Sleuth为 spring Cloud提供了分布式跟踪的解决方案&#xff0c;它大量借用了Google Dapper、 Twitter Zipkin和 Apache HTrace的设计&#xff0c;先来了解一下 Sleuth的术语&#xff0c; Sleuth借用了 Dapper的术语。 span&#xff08;跨度&#xff09;&#xff…

sleuth 链路追踪

一&#xff1a;什么是链路追踪 对于以前的单服务器项目而言&#xff0c;如果一个地方出了问题&#xff0c;很容易去找到。可是对于微服务架构项目来说&#xff0c;因为微服务太多&#xff0c;而且往往是一个微服务调用了很多其他的微服务&#xff0c;如果一个地方出错&#xff…

java sleuth配置

java sleuth配置 springCloud学习记录SpringCloud Alibaba sleuth&#xff08;分布式请求链路跟踪&#xff09;zipkinsleuthpomyml springCloud学习记录 SpringCloud Alibaba sleuth&#xff08;分布式请求链路跟踪&#xff09; 在微服务框架种&#xff0c;一个由客户端发起的…

Spring Cloud Sleuth+Zipkin 构建微服务链路跟踪系统

什么是链路跟踪系统&#xff1f; 在微服务中&#xff0c;多个服务分布在不同物理机器上&#xff0c;各个服务之间相互调用。如何清晰地记录服务调用过程&#xff0c;并在出现问题的时候能够通过查看日志和服务之间的调用关系来定位问题&#xff0c;这样的系统就叫做链路跟踪系…

SpringCloud Sleuth入门介绍

案例代码:https://github.com/q279583842q/springcloud-e-book 一、Sleuth介绍 为什么要使用微服务跟踪?它解决了什么问题&#xff1f; 1.微服务的现状&#xff1f; 微服务的现状   随着业务的发展&#xff0c;单体架构变为微服务架构&#xff0c;并且系统规模也变得越来…

Spring Cloud Sleuth HTTP详解

目录 1版本关系 2简介 2.1术语 2.2调用链可视化 2.2.1使用Zipkin进行分布式跟踪 2.2.2错误可视化 2.2.3使用Brave进行分布式跟踪 2.2.4将Sleuth添加到项目中 3调用信息生成与上报原理 3.1初始化配置类 3.2过滤器-请求过滤 3.3调用信息拦截 3.4调用信息上报 4日志…

Sleuth链路追踪

文章目录 Spring-Cloud-Alibaba-Sleuth链路追踪一、链路追踪介绍二、Sleuth入门演示&#xff1a; 三、ZipKin介绍ZipKin服务端安装ZipKin数据持久化 Spring-Cloud-Alibaba-Sleuth链路追踪 一、链路追踪介绍 在大型的微服务项目中&#xff0c;一个系统被拆分成许多模块&#xf…

sleuth原理详解

sleuth原理 1、关键术语 Span&#xff1a;Span基本工作单元&#xff0c;发送一个远程调度任务就会产生一个Span, Span 是用 64ID唯一标识的&#xff0c;Trace是用另一个64ID唯一标识的。Span还包含了其他的信息&#xff0c;例如摘要、时间戳事件、Span的ID以及进程 ID。Trace…

07-搭建微服务-链路追踪Sleuth

1、为什么使用链路追踪&#xff1f; 在微服务中&#xff0c;随着服务越来越多&#xff0c;对调用链的分析越来越复杂。 出现问题&#xff1a; 1、微服务之间的调用错综复杂&#xff0c;用户发送的请求经历哪些服务&#xff0c;调用链不清楚&#xff0c;没有一个自动化的工具类来…

sleuth入门

Sleuth介绍 SpringCloud Sleuth主要功能就是在分布式系统中提供追踪解决方案。它大量借用了Google Dapper的设计&#xff0c; 先来了解一下Sleuth中的术语和相关概念。 Trace 由一组Trace Id&#xff08;贯穿整个链路&#xff09;相同的Span串联形成一个树状结构。为了实现请求…

集成sleuth_Spring Cloud Sleuth整合zipkin过程解析

这篇文章主要介绍了Spring Cloud Sleuth整合zipkin过程解析,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 SpringCloud Sleuth 简介 Spring Cloud Sleuth为Spring Cloud实现了分布式跟踪解决方案。 Spring Clo…

集成sleuth_整合Sleuth

Sleuth是 springcloud 分布式跟踪解决方案。 Sleuth 术语&#xff1a; 跨度(span ) &#xff1a;Sleuth 的基本工作单元&#xff0c;他用一个64位的id唯一标识。出ID外&#xff0c;span还包含 其他的数据&#xff0c;如 描述&#xff0c;时间戳事件&#xff0c;键值对注解等&am…

Spring Boot 中的 Sleuth 是什么, 如何使用

Spring Boot 是一个非常流行的 Java Web 开发框架&#xff0c;它提供了许多方便的功能&#xff0c;其中之一就是 Sleuth。Sleuth 是一个分布式跟踪系统&#xff0c;用于跟踪应用程序中的请求和操作。在本文中&#xff0c;我们将探讨 Spring Boot 中的 Sleuth 是什么&#xff0c…

sleuth原理分析

背景 微服务模式下&#xff0c;一次请求可能会经过多个服务。如果没有日志链将单次请求的日志串起来&#xff0c;定位问题时很容易陷入海量的日志中&#xff0c;无法快速定位问题。 sleuth是spring cloud中日志链&#xff08;调用链解决方案&#xff09;&#xff0c;引入该依赖…

快速学习-Sleuth--链路追踪

Sleuth–链路追踪 6.1 链路追踪介绍 在大型系统的微服务化构建中&#xff0c;一个系统被拆分成了许多模块。这些模块负责不同的功能&#xff0c;组合成 系统&#xff0c;最终可以提供丰富的功能。在这种架构中&#xff0c;一次请求往往需要涉及到多个服务。互联网应用构建 在…

SpringCloud学习笔记(十二)Sleuth 分布式请求链路跟踪

目录 一、Sleuth介绍 1、为什么会出现这个技术&#xff1f;需要解决哪些问题&#xff1f; 2、是什么 二、搭建链路监控步骤 1、zipkin搭建安装 1&#xff09;下载 2&#xff09;运行jar 3&#xff09;运行控制台 4&#xff09;术语 2、服务提供者 cloud-provider-pa…

MySQL5种索引类型

一、简介 MySQL目前主要有以下几种索引类型&#xff1a; 1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引 二、语句 CREATE TABLE table_name[col_name data type] [unique|fulltext][index|key][index_name](col_name[length])[asc|desc] 1.unique|fulltext为可选…