C++入门基础—— 引用变量

article/2025/9/14 21:08:48

目录

什么是引用:

   引用的例子

引用的特性:

常量引用与非常量引用

使用场景

引用与指针的区别


什么是引用:

  引用的概念

  引用实际上就是取别名,提起这个名字就会让人知道是谁,谈起“鸡哥”就知道是坤坤,那么我们所说的引用变量,不是新定义了一个变量,而是给一个已经定义的变量取别名,编译器不会为引用变量开辟空间,它和被引用的实体共用一个空间,,

 

   

现有变量a,b是a的引用,a与共用一个空间,那么对a进行操作就相当于也会对b进行操作反之亦然

   引用的例子

  类型& 引用变量名 = 引用实体;
  在这里&不是取地址符,而是类型标识符的部分,在这个测试代码中b是a的引用,根据上面的概念它们的值和地址应该是相同的,我们可以看一下结果:


int main()
{int a = 10;int & ra = a;cout<<a<<" "<<ra<<endl;cout<<&a<<" "<<&ra<<endl;system("pause");return 0;
}

运行结果: 

结果确实和概念所说的一样,但是这其中还有我们所需要在了解的,a和b的地址相同,我们知道在a变量定义的时候会为它随机分配内存,但是引用变量b不同编译器不会为它分配内存,即引用变量b是根据自己即将引用的变量的地址分配的,所以在引用变量b定义时,必须初始化,而不能先声明,在赋值。也就是定义时就指向另一个已经定义了的变量,否则,引用变量将无法得知自己的地址,所以 int& b;这是错误的

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

引用的特性:

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

  在上面我们已经提到了,引用在定义是必须初始化,我们来测试一下

  

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

   就像一个人可以有多个别名,变量也可以有多个引用

int main()
{int a = 10;int& ra = a;int& raa = a;cout<<a<<" "<<ra<<" "<<raa<<endl;cout<<&a<<" "<<&ra<<" "<<&raa<<endl;return 0;
}

运行结果: 

与上面的没有区别,它们的值和地址都是相同,

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

          引用变量在引用某个变量后,在它的生命周期内,就不会成为其它变量的引用

举个栗子:定义变量a ,b是a的引用,定义变量c尝试是否可以使b引用a,(引用的特征:共用一块空间 那么我们看它们的地址,判断是否成功引用)

int main()
{int a = 10;int& ra = a;	int c = 100;cout<<a<<" "<<ra<<" "<<c<<endl;ra  = c;cout<<a<<" "<<ra<<" "<<c<<endl;cout<<&a<<" "<<&ra<<" "<<&c<<endl;system("pause");return 0;
}

 

运行结果: 


 

结果是b并没有成为c的引用,ra = c;不会成功,只会实现赋值的效果

常量引用与非常量引用

   我们上面说谈的都是非常量引用,非常量引用要求被引用的实体必须有左值(个人理解的左值:地址值),若引用的实体没有左值编译器会报错,

  常量引用 :常量引用也就是 const 类型& 引用变量名 = 引用实体 这里的引用实体常是常规常量、表达式,左右两侧的类型不同

int main()
{//int& a = 10;  编译报错 10 是常量const int& ra = 10;const int b = 10;//int& rb = b;  编译报错 b是一个常量const int& rb = b; int aa = 10;int bb = 20;int cc = aa + bb;//int& rcc = aa+bb;//编译报错 非常量引用的初始值必须为左值const int& rcc = aa + bb;system("pause");return 0;
}

常量引用创建临时变量

  由于类型不同,所以只能使用常量引用来引用a,但是这和非常量引用不同,ra和a不共用一个空间,编译器会创建一个于ra类型相同的临时的无名变量并初始化并将a赋值给它,,然乎ra就是这个无名变量的引用

int main()
{double  a = 13.4;const int& ra = a;cout<<a<<" "<<ra<<endl;// a = 13.4 ra = 13a = 20.6;cout<<a<<" "<<ra<<endl; //a = 20.6 ra = 13cout<<&a<<" "<<&ra<<endl; system("pause");return 0;
}

 

使用场景

  做参数

 C语言中给函数传参有两种方法:传值和传地址,在C++中有了第三种方法:传引用

void Swap(int& left, int& right){   int temp = left;   left = right;   right = temp; 
}

做返回值

int& add(int a, int b)
{int c = a+ b;return c;//return a + b// 编译报错  a+b不是左值 (表达式 常量 没有左值)
}
int& Count()
{static int n = 0;n++;return n;
}
int main()
{int& ret = add(1,2);//不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,//因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。int& r = Count();cout<<r<<endl;cout<<r<<endl;cout<<r<<endl;system("pause");return 0;//如果函数返回时,出了函数作用域,如果返回对象还未还给系统,则可以使用引用返回,//如果已 经还给系统了,则必须使用传值返回。}

以引用返回函数值,定义函数时需要在函数名前加 &

不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了"无所指"的引用,程序会进入未知状态。

如果函数返回时,出了函数作用域,如果返回对象还未还给系统,则可以使用引用返回,
如果已经还给系统了,则必须使用传值返回。

引用与指针的区别

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


通过汇编语言我们可以发现 它们的底层实现是完全相同的,引用的实现也是借用指针(先取地址,在解引用)

引用于指针的不同

1 引用变量在定义时必须初始化,而指针不用;
2 引用变量在引用一个实体后就不能引用其他实体,而指针在任何时候都可以指向一个同类型的实体

3 引用必须指向有效的空间,指针可以指向NULL

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

5 引用不能引用数组,指针可以

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

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

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

9 引用比指针使用起来相对更安全,没有野指针的危险
 

 

  

 


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

相关文章

C++——引用变量

目录 一、创建引用变量 二、将引用作为函数参数 三、引用的属性和特别处 四、临时变量、引用参数和const 五、返回引用 六、何使用引用参数 七、参考书籍 引用变量是C新增的一种复合类型。引用是已定义的变量的别名&#xff08;另一个名字&#xff0c;但两个名字都是表示…

014 变量的引用

目标&#xff1a; 1、变量的引用 2、可变和不可变量类型 3、局部变量和全局变量 一、变量的引用 。变量 和 数据 都是保存在 内存 中的 。在 python 中 函数 的 参数传递 以及 返回值 都是靠 引用 传递的 1.1 引用的概念 在 Python 中 。变量 和 数据 是分开存储的 。数据 保…

C语言动态内存分配函数

目录 1.malloc()2.free()3.calloc()4.realloc()5.小结 在C中我们开辟内存空间有两种方式 :1.静态开辟内存 : 例如: int a; int b[10]; 这种开辟内存空间的特点是 所开辟的内存是在栈中开辟的固定大小的 ,如a是4字节 ,数组b是40字节 ,并且数组在申明时必须指定其长度 , 如果是全…

【C语言】------ 动态内存分配

动态内存开辟详解 动态内存分配什么是动态内存分配&#xff1f; 一、为什么使用动态内存分配呢&#xff1f;二、动态内存函数1.malloc和free2.calloc和realloc 三、常见的动态内存错误1.对NULL指针的解引用操作2.对动态内存开辟的越界访问3.向free传递一个非malloc函数返回的指…

【C语言】为什么存在动态内存分配

文章目录 前言一、动态内存分配定义 二、动态内存分配的意义1.可以控制所开辟的内存大小2.可以多次利用这部分空间 三&#xff0c;动态内存函数的介绍 前言 提示&#xff1a;我们先来看一个在vs编译器下&#xff0c;同学们常犯的错误 注意&#xff1a;在VS编译器下C语言是不支…

静态内存分配与动态内存分配

静态内存分配与动态内存分配 动机 平时看c/c的书籍时&#xff0c;总会看到一种观点&#xff0c;说是C/C语言使用的时候动态内存分配是最重要的&#xff0c;使用malloc等函数分配的内存必须要释放&#xff0c;否则及其容易出现内存泄露。但是自己有时候挺奇怪的&#xff0c;啥…

JVM内存分配机制

Java虚拟机最重要的工作就是如何给对象分配内存空间&#xff0c;以及通过GC如何回收已经不再使用的内存空间。这篇文章主要介绍JVM中的Java对象是创建过程、对象内存的分配机制以及对象内存的回收机制。 一、对象的创建 在前面的文章《JVM类加载机制》中讲过&#xff0c;JVM中…

C语言动态内存分配详解

文章目录 前言一、为什么存在动态内存分配1、已掌握的内存开辟方式2、上述开辟空间方式的特点3、为什么存在动态内存分配 二、动态内存函数的介绍1、malloc2、free3、calloc4、realloc 三、常见的动态内存错误1、对NULL指针的解引用操作2、对动态开辟内存的越界访问3、对非动态…

动态内存管理(内存的分配与回收)详解

** 1. 数据结构之动态内存管理机制 ** 通过前面的学习&#xff0c;介绍很多具体的数据结构的存储以及遍历的方式&#xff0c;过程中只是很表面地介绍了数据的存储&#xff0c;而没有涉及到更底层的有关的存储空间的分配与回收&#xff0c;从本节开始将做更深入地介绍。 在使…

关于C++的动态内存分配

为什么要使用动态内存分配&#xff1f; 比较常见的情况是当我们使用一个数组时&#xff0c;我们需要去声明它&#xff0c;同时我们还需要提供给它一个编译时常量用于指定数组的长度。但是&#xff0c;我们有时候需要的数组并不是定长的。例如&#xff0c;我们要存储一个班级所…

【C语言】动态内存的分配

目录 &#x1f34b;&#x1f34b;前言 &#x1f34b;&#x1f34b;动态内存分配的定义 &#x1f34b;&#x1f34b;动态内存的优势 &#x1f34b;&#x1f34b;<1> 可以控制内存的大小 &#x1f34b;&#x1f34b;<2> 可以多次利用这部分空间 &#x1f34b;…

动态内存分配函数

一、静态存储分配与动态存储分配&#xff1a; &#xff08;1&#xff09;静态存储分配 通常定义变量&#xff08;或对象&#xff09;&#xff0c;编译器在编译时都可以根据该变量&#xff08;或对象&#xff09;的类型知道所需内存空间的大小&#xff0c;从而系统在适当的时候…

内存动态分区分配算法

文章目录 动态分区分配1. 首次适应算法&#xff08;First Fit&#xff09;2. 邻近适应算法&#xff08;Next Fit&#xff09;3. 最佳适应算法&#xff08;Best Fit&#xff09;4. 最坏适应算法&#xff08;Next Fit&#xff09; 总结 动态分区分配 所谓动态分区分配&#xff0…

C++之new动态分配内存生成数组

【任务1】&#xff1a; 编写并测试3*3矩阵转置函数&#xff0c;使用数组保存3*3矩阵。 实验要求 &#xff08;1&#xff09; 转置函数参数为二维数组&#xff1b; &#xff08;2&#xff09; 在main函数中实现输入、输出 #include <iostream> using namespace std…

C语言中的动态内存分配

大家好&#xff0c;今天简单讲一讲C语言中的动态内存分配。 补充&#xff1a;C程序中的内存块。 在C程序中&#xff0c;通常将内存划分为以下六个区域&#xff1a; &#xff08;1&#xff09;内核区域。这块区域是操作系统的&#xff0c;用户不能使用。 &#xff08;2&…

C语言动态分配内存

C语言动态分配内存 malloc 动态开辟内存的函数&#xff1a; void* malloc (size_t size); 这个函数向内存申请⼀块连续可⽤的空间&#xff0c;并返回指向这块空间的指针 如果开辟成功&#xff0c;则返回⼀个指向开辟好空间的指针 如果开辟失败&#xff0c;则返回⼀个NULL…

C/C++动态分配内存的几种方法

使用C/C编程时&#xff0c;会经常动态分配内存&#xff0c;以便合理使用内存&#xff0c;本文主要讲述动态内存分配的几种方法及一些原理&#xff0c;理解不深刻之处欢迎指教。 引言 为什么要进行动态内存分配&#xff1f;以数组为例&#xff0c;数组元素在内存中存储的地址是…

sadad

出版社&#xff1a; 河北少年儿童出版社 ISBN&#xff1a;12176804 版次&#xff1a;1 商品编码&#xff1a;12176804 包装&#xff1a;精装 丛书名&#xff1a; 幼儿家庭课堂 开本&#xff1a;12开 出版时间&#xff1a;2017-05-01 用纸&#xff1a;铜版纸 适读人群 &#xff…

SAADC

电流 :EasyDMA draws about 1.2 mA, and added to the 700 uASAADC current it sums to ~2 mA。和实测差不多 官方例程解析:TIMER + PPI +SAADC。 特征: 1、 支持8/10/12位分辨率,和14位过采样分辨率 2、 8通道:单端输入最多可同时配置8个通道 和 差分输入…

SAZS~

本文提出了一种新颖的形状感知零样本语义分割&#xff08;SAZS&#xff09;框架&#xff0c;利用大规模预训练视觉语言模型特征空间中丰富的先验知识&#xff0c;并通过在边界检测约束任务上进行联合训练来融合形状感知 论文链接&#xff1a;https://arxiv.org/abs/2304.08491…