C++入门——引用

引用

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

我们在使用b这个变量的时候,即是访问a这一块空间,对a的改变便是对a的空间的改变,自然会改变b,而对b的操作是对b这块空间的操作,也会改变a。

引用的底层即为指针,而引用和指针的区别是,引用不使用新的空间,而指针需要开辟一块新的空间来存储指针变量

引用的使用

1.引用的定义

我们在一个数据类型后加上&,此时就代表该类型为引用类型

我们修改a,b也会随之修改

而我们输出a和b的地址,我们发现a和b的地址是相同的

 2.常引用

我们可以通过指针来类比,指针无法指向一个常数的地址,引用同样无法引用一个常数

所以我们在初定义引用时,我们无法引用一个常变量

但是,我们却可以使用常引用

 此时a仍是b的别名,而b是一个常变量,a是一个变量,我们可以改变a的值,b的值会随着a的值的改变而改变,却无法单独改变b的值

 

 

 

 此时,我们便引入了一个权限问题

权限

我们在C语言中初步了解的权限为变量和常变量的权限不同。变量的权限非常广,可以访问,修改和删除,而常变量的权限则会相对低一点,常变量无法进行修改。我们将变量变成常变量,即进行了权限的缩小,而将常变量变成变量,则进行了权限的放大,让一个变量等于另一个变量,则进行了权限的平移。

在引用中有这样一条规定:引用无法进行权限放大,引用只能缩小权限或平移权限,否则会导致空间访问的冲突

 我们给a取别名b,即进行了权限的平移,把a的权限平移给了b;而我们让const int& b=a,则是进行了权限的缩小,把a的权限缩小给了b。但是,如果我们给一个常变量取别名,则会产生权限的放大,因此编译器会报错。

了解了以上这些,我们来看一段代码:

我们发现,编译器报错了,我们可能会认为是类型不同无法进行引用,而我们将代码进行修改

我们发现,此时编译器并没有报错,也就证明了我们的猜想是错误的,那么真正的原因是什么?

我们在C语言知道,如果赋值的数类型不同,那么编译器会对其进行类型转换

所以,在不同类型的赋值中,我们看似是将a赋值给了b,实际上是将1赋值给了b

 此时,问题的答案便很清晰了:不同类型的引用,我们实际上是让b引用了一个常数,而非引用了一个变量,所以我们对b进行了权限的扩大,自然编译器会报错。

而在类型前加上const,我们进行了权限的平移,故而该操作是合法的。

3.引用作为参数

在C语言里,我们想实现Swap函数,常常会使用指针传参来实现

 而在C++中,有了引用这一语法,我们可以对其进行优化

根据引用的特征,引用作为参数,实际上参数是传入值的别名,也就是传入的变量和参数共用一块空间,我们对参数的修改即是对空间的修改,故而可以影响到传入的变量

4.引用作为返回值

我们可以将引用作为参数,同样可以将引用作为返回值。

比如该函数,我们在函数内部定义了一个新变量i,我们的返回值类型是int&,返回值是i的别名,故我们在访问这个返回值时,访问的是i所在的空间。但是我们都知道,在函数中的局部变量出作用域后即销毁,我们访问的是一个野空间,我们输出i的结果

我们惊讶地发现,输出结果居然还是6,难道这里的i没有被销毁吗?

我们再输出以下结果:


我们这时候发现,j突然变成了一个随机值,为什么?

栈帧

我们在调用函数时,会对函数进行一个压栈的行为

在函数被调用时,函数会在main函数上进栈,而函数调用完成,函数便会出栈,此时该栈空间即为野空间。所以我们访问这个野空间的时候,仍会保留出栈前的值 而等下一个函数被调用再一次进栈,野空间的值就会被修改,此时我们再去访问这个空间的值,我们实际访问的是被修改后的值。

我们通过以下程序来验证

 所以,我们想进行引用作为返回值,我们必须传回一个全局变量,或在局部变量前加上static

 引用的注意点

1.引用必须初始化

不同于指针可以先定义后赋值,引用必须进行初始化

 2.引用无法修改

通过必须初始化我们便可以知道,引用初始化后便无法修改,只能删除。

3.引用类型必须相同

我们在权限中已经说明了这个问题,如果想进行非相同类型的引用,我们必须要在前加上const

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值