一、引用的定义
引用:引用是一种便捷的传递聚合类型数据的方式,
1、 什么是引用?引用的本质,
C语言阶段学过赋值,如b = a;本质是把存储在名为a的内存下的值复制一份,放在名为b的内存下,通过赋值,b可以使用a的值做很多事,比如算术运算,
进而还学了指针,如:b = &a,指针是通过将将a的地址记录在变量b下,我们可以通过指针来间接操作a的值,
而引用和指针有些相似,但是引用是直接获得a的地址,然后给这块地址取个别名叫做b,此时b可以完全代表a。对引用的操作与对变量直接操作完全一样。
创建引用:定义的其格式为:类型 &引用变量名 = 已定义过的变量名
int a = 10;//声明普通变量
int& b = a;//声明引用变量
我们分别打印a和b的地址和值
cout<<"a = "<<a<<" &a = "<<&a<<endl;
cout<<"b = "<<b<<" &b = "<<&b<<endl;
运行结果:
a = 10 &a = 0x61fe88
b = 10 &b = 0x61fe88
从结果不难看出,a和b的值与地址都相同,说明a与b的本质都是一样的,都是10对应的那块地址,只是命名不同。所以引用就是起别名。
2、引用的特点
1)、引用必须初始化
2)、引用只能在初始化的时候引用一次 ,不能更改为转而引用其他变量
3)、一个变量可以有多个引用,一个引用只能对应一个变量
3、引用与指针
引用和指针的区别:
引用 |
指针 |
|
本质 |
别名 |
是变量实体, |
使用 |
无需取(*),直接访问 |
需要取(*)间接访问 |
不能多级引用,只能一级一级的 |
可以有多级指针 |
|
定义 |
必须初始化,不存在空引用 |
不一定要初始化,可以为空 |
大小 |
sizeof得到引用值的大小 |
sizeof得到指针变量自身的大小 |
自增 |
++/--:得到的是值加1 |
++/--:得到的是地址加1, |
总结:引用更高效,更安全,指针更加灵活,功能更加全面,两者都是地址的概念 |
单独看一下引用与指针自加(减)运算的区别:
#include <iostream>
using namespace std;
int main()
{
int arr[3] = {10,20,30};
int& c = arr[0];
c++;
cout<<"c++ = "<<c<<endl;
int* p = &arr[0];
p++;
cout<<"p++ = "<<*p<<endl;
return 0;
}
运行结果:
c++ = 11
p++ = 20
二、引用实例
const引用:
int a = 10; //声明普通变量
int& b = a; //声明引用变量
//可以通过给b赋值来改变a的值,如:b = 20;
const int& c = a; //被const修饰的引用称为常引用
//不能通过给c赋值改变a的值 //不能c = 20;
//但是被const修饰的引用初始化可以引用常量,直邮常引用可以引用常量
const int& d = 10;
把引用做参数:
#include <iostream>
using namespace std;
void func(int& x, int& y) //交换函数
{
int c;
c = x;
x = y;
y = c;
return;
}
int main()
{
int a = 10;
int b = 20;
cout<<"交换前,a = "<< a <<endl;
cout<<"交换前,b = "<< b <<endl;
//调用函数交换a、b的值
func(a, b);
cout<<"交换后,a = "<< a <<endl;
cout<<"交换后,b = "<< b <<endl;
return 0;
}
执行结果如下:
交换前,a = 10
交换前,b = 20
交换后,a = 20
交换后,b = 10
总结:
(1)将变量名作为实参和形参传递,这时传递的是变量的值,是单向传递,函数内部对形参的操作并不能传递给实参,值传递的本质时把实参的值复制一份给形参,函数执行是作用在形参上的,存储形参的空间地址会随着函数的调用的结束而释放。
(2)传递变量指针:形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种通过形参指针可以改变实参的值。
(3)C++提供了传递变量的引用。形参是引用变量,实参是变量名,实际上形参和实参是一个变量,调用函数时,形参(引用变量)指向实参变量单元。这种通过形参引用可以改变实参的值,且不需要创建副本也无需重新定义指针变量。
把引用作为返回值:
#include <iostream>
using namespace std;
int a[4] = {1,2,3,4};
int& func(int i)
{
int &n = a[i];
return n;
}
int main()
{
cout<<"改变前的值:"<<endl;
for(int i = 0; i < 4; i++)
{
cout << "a["<< i <<"] = " << a[i] << endl;
}
func(1) = 100;
func(2) = 200;
cout<<"改变后的值:"<<endl;
for(int i = 0; i < 4; i++)
{
cout << "a["<< i <<"] = " << a[i] << endl;
}
return 0;
}
运行结果:
改变前的值:
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
改变后的值:
a[0] = 1
a[1] = 100
a[2] = 200
a[3] = 4
我们发现我们可以通过给函数赋值来改变原有数据,而不只是用变量接函数的返回值。
注意:当返回一个引用时,引用的对象不要超过被引用对象的作用域