1、引用的定义
引用就相当于给变量起别名,引用的本质就是一个指针常量,指针指向的的值可以修改,指向的内存地址不能改变。
语法 :数据类型 &别名=原名
int a=10;
int &b=a;//引用
注意事项:
1、引用必须初始化,并且初始化后不可以改变(如果已经为a的别名,就不能更改为c的别名)
2、没有引用数组或指针,没有引用的引用。
int a = 10;
int b = 20;
int &c = a;//引用,c相当于是a的别名
c = b;//这是赋值操作,不是更改引用,相当于c=20
cout << "a为" << a << endl;//a为20,因为a和c操纵的是同一块内存
引用做函数参数
作用:函数传参时,可以利用引用让形参修饰实参
优点:可以简化指针修改实参
//1、值传递
void swap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
//2、地址传递
void swap2(int*p, int*s)
{
int temp = *p;
*p = *s;
*s = temp;
}
//3、引用传递
void swap3(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
swap1(a, b);//值传递,形参不会修饰实参
swap2(&a, &b);//地址传递,形参会修饰实参
swap3(a, b);//引用传递,形参会修饰实参
引用做函数参数返回值
//返回局部变量的引用
//1、不能返回局部变量的引用
int & test01()//加上&之后,就是用引用的方式做一个返回
{
int a = 10;//局部变量,存放在栈区,test01执行完成后,a就被释放掉
return a;
}
//返回静态变量的引用
//2、函数的调用可以作为左值
int & test02()
{
static int a = 20;//静态变量,存放在全局区,全局区的数据在程序结束后由系统进行释放
return a;
}
int main()
{
int &ref1 = test01();
cout << "ref1=" << ref1 << endl;//第一次结果正确,是因为编译器做了保留
cout << "ref1=" << ref1 << endl;//第二次结果错误是因为a的内存已经被释放,再去操作就是非法操作
int &ref2 = test02();
cout <<"ref2="<< ref2 << endl;
test02() = 30;//相当于a=30;a与ref2都是test02的别名
//如果函数的返回值是引用,这个函数调用可以作为左值
cout <<"ref2="<< ref2 << endl;
}
引用的本质
引用的本质在C++内部就是一个指针常量(即指针的指向是不可以修改的,指针指向的值可以修改)。
补充:指针常量与常量指针
- 指针常量:int*const cp_a=&a ;指向不可改,指向的值可以改;(指针是常量)
- 常量指针:const int*p_ca=&a ;指向可改,指向的值不可改;(常量的指针)
//发现是引用,转化为int *const ref=&a
void func(int &ref)
{
ref=100;//ref是引用,转化为*ref=100;
}
int main()
{
int a=10;
int &ref=a;//发现是引用,转化为int *const ref=&a
ref=20;//ref是引用,转化为*ref=20;
cout<<a<<endl;
cout<<ref<<endl;
func(a);
}
常量引用
作用:常量引用主要用来修饰形参,防止误操作。
在函数形参列表中,可以加const修饰形参,防止形参改变实参。
首先需要明确的是,形参改变实参这种情况只可能发生在地址传递或者引用传递中,“防止形参改变实参”的意思是:在函数中可能会对形参的值进行修改,由于是引用传递,实参的值也会跟着改变,但是有时又不想实参的值跟着改变,那么就可以用const来修饰形参。那么,如果想改变形参的同时不改变实参,那么为什么一开始就不用值传递呢,因为值传递在数据量大的时候会消耗大量的内存,而引用传递可大大降低内存的使用。
//常量引用:用来修饰形参,防止误操作
void printValue(const int&val)
{
//val = 20;//防止修改实参
cout << "val=" << val << endl;
}
int main()
{
int a = 10;
int&ref = a;//可以
//int &ref = 10;//错误的,引用必须引一块合法的内存空间
const int &ref1 = 10;//可以,相当于编译器对代码做了优化,优化后:int temp=10;const int&ref=temp;
printValue(a);
cout << "a=" << a << endl;
}