前言:
作者简介:大家好,我是翼同学,一名大学生。
个人主页:翼同学的CSDN博客
系列专栏:C++学习笔记
备注:如果文章有误,请指正,万分感谢!让我们一起学习,一起进步。
✅最后:如果文章对您有帮助,请三连支持一下博主哦。
我们使用引用来给已经存在的变量赋予别名,这样,我们就可以使用该别名来指向变量
- 引用就是别名
- 对引用的修改就相当于对实际目标的修改
创建引用时,我们先写上目标的数据类型,后接&,再加上别名,最后把目标赋给引用即可
举例:
int var = 4;
int& v = var;
在这里,我们声明v是变量var的引用。
如下:
- 引用的变量必须已经声明了或定义了(即在上述代码中,变量
var
必须已经声明了)- 引用在声明是必须初始化(即
int & v;
是错误的,其未初始化)- 引用运算符&只在声明时使用,其余情况都是指取地址运算符
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象
- 实际上,引用的地址就是其引用的对象的地址(求引用本身的地址其实并无意义)
- 指针也是内存实体,所以指针也可以有引用,比如:
int* var;
int* & v = var;
- 不存在空引用,即
int & v = NULL;
这条语句毫无意义
传递引用给函数和传递指针给函数,效果都一样。即传递的是目标对象,而不像值传递一样在函数作用域内建立变量的副本。
实例:
#include
using namespace std;
int exchange(int& a,int& b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int x=1,y=2;
cout<<"x,y交换前的值分别为:"<<x<<" "<<y<<'\n';
exchange(x,y);
cout<<"x,y交换后的值分别为:"<<x<<" "<<y<<'\n';
return 0;
}
运行结果为:
x,y交换前的值分别为:1 2
x,y交换后的值分别为:2 1
引用的威力和指针相当,且可读性比指针好。
在C++中,引用类型主要作为函数参数,以增加函数传递数据的功能,更加灵活。
引用作为函数形参时,调用函数后,形参(引用变量)指向实参变量单元。这种通过形参引用可以改变实参的值。
把引用作为参数传递的函数,调用时不能传入常量。
我们知道,函数只能返回一个值。但是我们可以通过在函数参数里增加若干个对象的引用,这能实现改变多个对象的值的功能,相当于让函数返回多个值。
实例:
#include
using namespace std;
void func(int n,int& a,int& b)
{
a = n*n;
b = n*n*n;
}
int main()
{
int var,square,cube;
cout<<"请输入10以内的整数:\n";
cin>>var;
func(var,square,cube);
cout<<var<<"的平方为:"<<square<<'\n'
<<var<<"的立方为:"<<cube;
return 0;
}
运行结果:
请输入10以内的整数:
4
4的平方为:16
4的立方为:64
我们在引用的最前面加上关键字const便成了常量引用。
我们在函数的参数中使用引用,但如果此时我们不想让引用的对象被修改了,就可以使用const关键字进行修饰引用,这会使实参不被修改。
举例:
上述代码表明,我们对引用使用
const
修饰后,其作用就是使目标成为const常量
我们知道,函数在返回值时,会产生一个值的副本。但是,我们用引用返回值时,不会生成值的副本。/这是用返回引用的一大好处。
语法:在函数名前加上
&
运算符。
- 即:
数据类型 &函数名(形参列表){ 函数体 }
引用返回的形式一共有4种,代码如下:
#include
using namespace std;
const double PI = 3.141592;
double temp;
double get_girth_1(double r)
{
temp = 2*PI*r;
return temp;
}
double& get_girth_2(double r)
{
temp = 2*PI*r;
return temp;
}
int main()
{
double girth_a = get_girth_1(3.0); //方式1
//double& girth_b = get_girth_1(3.0); //方式2 错误
double girth_c = get_girth_2(3.0); //方式3
double& girth_d = get_girth_2(3.0); //方式4
cout<<girth_a<<'\n'
<<girth_c<<'\n'
<<girth_d;
return 0;
}
运行结果如下:
18.8496
18.8496
18.8496
说明:
在这四种引用返回的形式中,方式2有误,其余三种方式的运行结果是一样的,但其实它们在内存中的情况是不同的。其中,变量temp
是全局变量,存储在全局数据区data
中。主函数main()
,函数get_girth_1()
,get_girth_2()
的数据都存储在栈区stack
中。
方式1是一般的函数返回值方式,返回全局变量
temp
时,C++会创建临时变量,并将temp
的值复制给这个临时变量。返回主函数后,语句double girth_a = get_girth_1(3.0);
把临时变量的值复制给变量girth_a
。这是合法的。
方式2与方式1类似,也把
temp
的值复制给某个临时变量,但在返回主函数后,临时变量的值却赋值给了一个double
类型的引用,double& girth_b = get_girth_1(3.0)
,很显然,引用girth_b
以某个临时变量来初始化,这是错误的。如果非要以返回值来初始化一个引用,则需要先创建一个变量来接收临时变量的值,再把这个变量赋值给引用,比如:
double x = get_girth_1(3.0);
double& girth_b = x;
方式3中的函数
get_girth_2()
的返回值不产生副本,所以直接将全局变量temp
的值返回给主函数。即左值girth_c
直接从全局变量temp
那得到赋值。这就避免了临时变量的产生,使程序的执行效率和空间利用得到了提升。
方式4返回了一个引用,这也不产生任何返回值的副本。在主函数中也用了double类型的引用
girth_d
去接收返回值。这使得girth_d
成为全局变量temp的引用(别名),由于temp
是全局变量,这使得在引用girth_d
生命期内temp的值都有效。
注意事项如下:
文末备注:参考书:《C++程序设计教程》----钱能 著
好了,引用的总结就到这里,下一节我们看C++中的类!