[C++基础]---引用&的详解

本文详细介绍了C++中的引用概念,包括其与指针的区别,如引用是变量别名、无需额外空间,以及引用在函数参数和返回值中的使用。同时对比了传值与传引用的效率差异,强调了引用在编程中的优势和安全特性。
摘要由CSDN通过智能技术生成

目录

引用的概念

引用的特性

1.特性

2.讲解

常引用

引用的使用

1.引用做函数的参数 

2.引用做函数返回值

传值和传引用返回对比 

引用和指针的区别


在C语言的学习中,我们学习了对指针的使用。而在C++中我们引用另一个有效的工具--引用。本篇文章将为问题很多的小明详细介绍“引用”。 

引用的概念

概念: 

引用并不是新建一个变量,而是对已有变量取一个别名。由于这个特性,引用并不会新开辟空间,而是同已有的变量公用同一块空间。

 例如:每位同学都有自己的名字,而问题很多的小明就是给大家取得别名。但是指向的都是每一个人自己本身。

使用:

引用符号:&

类型+&+变量 = 引用实体

举个例子:

int a = 1;
int&b = a;
printf("%p %p",&a,&b);

我们打印出地址可以发现,a和b指向的地址相同。所以,我们可以对之前的概念,引用变量和实体指向的地址相同。

 

既然二者的地址指向同一块空间,那么对变量的修改就会使实体的值也改变。 

int a =10;
int&b = a;
std::cout<<a<<' '<<b;
 b =20;
std::cout<<a' '<<b;

打印的最终结果如下: 

所以我们可以发现,一旦引用后,对变量的修改也会对实体造成影响。就好比,我打了孙悟空和我打了孙行者造成的效果是一样的,因为“孙悟空”和“孙行者”都指向同一个人。 

此外,在引用的时候,我们的引用变量的类型必须与原来的实体类型相同。实体类型是什么,引用的变量就要是什么类型。 

引用的特性

1.特性

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

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

3.引用一旦引用一个实体,就不能应用其他实体。 

2.讲解

我们通过代码来对引用的特性进行讲解。

int a = 10;
int& ra; // 没初始化,会报错
int& ra = a;
int& rra = a;
int& rrra = a;
//这三个都是a的引用,只要其中一个
//发生改变,其他三个也会改变
printf("%p %p %p %p\n", &a, &ra, &rra, &rrra);  

根据第一部分的讲解,我们可以知道ra,rra,rrra的地址都和实体a的地址相同,因此修改任一一个其他的几个也会改变。 通俗来讲,就是一个人可以有多个别称。

常引用

引用也可以用于常量的类型,根据引用概念中变量类型必须与实体类型一致可以知道,在进行常引用时,类型需要加上const。 

const int a = 10;
//int& ra = a;   // 该语句编译时会出错,a为常量
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量

const int& b = 10;
double d = 12.34;
//const int& rd = d; // 该语句编译时会出错,类型不同
const double& rd = d;

 通过这一板块的讲解,相信大家对引用中类型的设置有了更深的理解。

引用的使用

1.引用做函数的参数 

与C语言不同的是,在C语言中,实参传递的形参只是一份数据的拷贝,对实参无法产生影响,只有传输地址才能对实参产生影响。但在C++中,有了引用,我们就不需要传输地址! 

void Swap(int& left, int& right)//交换函数
{
   int temp = left;
   left = right;
   right = temp;
}
int main{
int a = 10;
int b = 20;
Swap(a,b);//因为形参为引用,所以这传的是a,b的引用
}

从上述代码可以看到,如果我们想要改变实参,只需在外部函数中进行引用。

这里需要注意的是,引用做函数参数的时候,依旧需要带类型,若不带类型则为取地址。 

2.引用做函数返回值

引用在用作返回值时,若出了函数变量未被销毁,则可以直接在函数外部对函数内部进行修改。 

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

int main()
{
int ret = Count();
cout<<n<<endl;
return 0;
}

大家可以思考上述代码的输出结果。

大家打印的结果可能是1,也可能是随机值。为什么会出现这种情况呢?

因为这里的返回并不是返回n,因为n在这里是局部变量,当n出了Count函数,n便被销毁了,返回值是通过已经在main函数里创建好的临时变量存下n的值返回的。 

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

int& tmp = Count();
tmp = 20;
cout << tmp << ' ' << n;

我们将n定义为静态变量,并通过引用在外部尝试修改n的值 。

得到的输出结果如下: 

我们再来分析下面这段代码

int&count()
{
   int  n = 0;
   n++;
   return n;
}

int main()
{
   int&ret = count();
   count<<ret<<endl;
   count<<ret<<endl;
   return 0;
}

很多同学会认为两次输出值相同,实际上是不同的,第二次的输出会是一个随机值。

 

原因是,由于这里使用了引用,所以这里的ret就和n公用一块空间。在第二次调用时会将原空间进行覆盖,所以打印的出的是一个随机值。所以这里我们可以知道引用是对原空间的直接覆盖。 

传值和传引用返回对比 

在前面我们介绍到,传值返回是通过中间的临时变量进行返回,如图。

 

而对于传引用返回则不需要建立临时变量,而是直接修改返回。 

所以,我们可以得到如下结论:用值作为参数或者返回值类型效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低 。

引用和指针的区别

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

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

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

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

 5.在sizeof种,引用的结果时引用类型的大小,而指针始终是地址空间所占字节数。

 6.引用++是对引用的实体+1,而指针++是向后移动一个类型大小。

 7.有多级指针,但无多级引用。

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

9.引用比指针使用更加安全。

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值