1、引用的基本使用
引用的作用:给变量起别名
语法:数据类型 &别名 = 原名
为什么a输出的也是20?
因为不管我们呢是用原名a来操作它,还是用别名b来操作它,我们所修改的都是同一块内存。
回忆:操作系统中讲的共享
2、引用的注意事项
引用必须初始化
引用在初始化后,不可以再改变了!
点击查看代码
int main()
{
int a = 10;
int b = 20;
int &c; //错误!引用必须初始化!
int &c = a; //正确,初始化引用,给a起个别名为c
c = b; //赋值操作,并不是更改引用。
}
3、引用做函数参数
作用:函数传参时,可以利用引用的技术让形参修饰实参。
优点:可以简化指针修改实参(可以不用指针直接修饰实参)。
几种函数参数形式的对比:
1、值传递
形参不会改变(修饰)实参
点击查看代码
void mySwap1(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
mySwap1(a , b); //调用方式
2、地址传递
形参会修饰实参
点击查看代码
void mySwap2(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
mySwap2(&a, &b); //调用方式
3、引用传递
形参会修饰实参
点击查看代码
void mySwap3(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
mySwap3(a , b); //调用方式
总结:
通过引用参数产生的效果同按地址传递是一样的,但是引用的语法更清楚简单。
4、引用做函数返回值
作用:引用时可以作为函数的返回值存在的。
注意:不要返回局部变量引用。
用法:函数调用作为左值。
当一个函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。
点击查看代码
//返回局部变量的引用
int & test1()
{
int a = 10; //局部变量存放在栈区中,在程序执行完就被释放了
return a;
}
//返回静态变量的引用
int & test2()
{
static int a = 20; //静态变量,存放在全局区,全局区上的数据在程序结束后由系统释放
return a;
}
int main()
{
//不能返回局部变量的引用
int &ref = test1();
cout << "ref = " << ref << endl; //第一次结果正确,是因为编译器做了保留
cout << "ref = " << ref << endl; //第二次结果错误,输出的是一堆乱码,因为a的内存已经释放
//但X86环境下会给你保留一次 X64环境下一次都不会保留(两次都是乱码)
//如果函数作为左值,那么必须返回引用
int &ref2 = test2();
cout << "ref2 = " << ref2 << endl; //输出为10
test02() = 1000; //函数作为左值,实际上就是将函数返回的a的引用赋值为1000,即 a = 1000;
cout << "ref2 = " << ref2 << endl; //输出为1000
cout << "ref2 = " << ref2 << endl; //输出为1000
//为什么输出ref2也是1000,因为ref2是test2()函数的返回值的别名,即a的别名
}
5、引用的本质
引用的本质在C++内部实现一个指针常量
点击查看代码
void func(int &ref) //引用传递参数
{
ref = 100; //ref是引用,转换为*ref = 100
}
int main(){
int a = 10;
//自动转换为 int *const ref = &a; (指针常量), 指针常量是指针指向不可改,也说明为什么引用不可更改
int &ref = a;
ref = 20; //内部发现ref是引用,自动帮我们转换为 *ref = 20;
}
结论:C++推荐用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了
6、常量引用
作用:常量引用主要用来修饰形参,防止误操作
在函数形参列表中,可以加 const 修饰形参,防止形参变实参
点击查看代码
int &ref = 10; // 引用本身需要一个合法的内存空间,因此这行错误
const int & ref = 10; //假如const就可以了,编译器优化,int temp =10; const int &ref = temp;
ref = 100;//错误,加入const后ref就不可更改变量了。
//在函数中利用常量防止误操作修改实参
void func( const int &a)
{
a = 100; // 错误,参数a传进来就是常量,无法修改
}