1.引用的概念以及用法和特点
1.1概念:
引用不是定义一个新的变量,而是给你一个已经定义变量取一个别名。
1.2定义的格式:
类型& 别名=已经定义的变量名
1.3 特点
1.3.1一个变量可以有多个名字。
1.3.2引用必须初始化。
1.3.3 引用只能在初始化的时候引用一次, 不能再改变为引用其他变量。
2.引用做参数
我们用值传递、引用传递、指针传递 做比较。
void Swap1(int a,int b) { //实际上是无法交换的。
int tmp = a;
a = b;
b = tmp;
}
void Swap2(int& a, int& b) { //如果形参是引用类型,那么形参成就是实参的别名。
int tmp = a;
a = b;
b = tmp;
}
void Swap3(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
int l = 1;
int r = 2;
cout << "交换前: " << l <<" "<< r << endl;
Swap1(l,r);//无法交换
cout << "传值交换: " << l << " " << r << endl;
Swap2(l, r);//
cout << "引用交换: " << l << " " << r << endl;
Swap3(&l, &r);
cout << "指针交换: " << l << " " << r << endl;
return 0;
}
结构体实例:
#include<iostream>
using namespace std;
typedef struct Big {
int b[10000];
}Big;
void LookBig1(Big& b) {
}
void LookBig2(Big& b) {
}
void LookBig3(Big* b) {
}
int main() {
Big big;
LookBig1(big); //big直接传给b的同时要开辟大量的空间,浪费资源也降低了效率。传值要40000个字节的空间浪费
LookBig2(big); //b就变成了big的别名,不用再开辟大量的空间。
LookBig3(&big);//传地址过去,有了地址想怎么玩就怎么玩,也不会开辟大量的空间。传值仅开辟4个字节的空间
return 0;
}
3.引用做返回值
![](https://i-blog.csdnimg.cn/blog_migrate/0c44e1785af11e0e7eb5a7947405a4e9.png)
ACD能运行通过,C则不行。
原因在于:函数add运行时a和b的和的值赋给了一个临时变量,
此时这个临时变量的权限仅仅只有读,然后临时变量再赋给函数返回值ret,main函数中的ret就变成了add函数的返回值ret的别名,main函数中的ret权限为读写,add函数返回值ret权限位只读,权限符合,因此编译器报错。解决这样的问题方法有C,D。C:const 使
int& ret的权限和add相同,只有读的权限。D:此处直接引用,内存空间就不会生成临时变量,访问权限就不会受限。因此程序运行通过。
4.汇编层看引用的特性
通过汇编看函数栈帧调用:
int add(int a,int b){return a+b;}
void test(){
int ret =add;
}
int main(){
test():
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/f137a672194ab2bb706c52ccb398c39f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/29edcdd615e984cd6119f66cbd5d219a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/10388f18bb2921dc3a13ab8642f39179.png)
总结:1.不要返回一个临时变量的应用. 2.如果返回对象出了当前函数的作用域依旧存在,则最好使用引用返回,因为这样更高效。
5.引用和指针的区别
1. 引用只能在定义时初始化一次,之后不能改变指向其它变量(从一而终);指针变量的值可变。
2. 引用必须指向有效的变量,指针可以为空。
3. sizeof指针对象和引用对象的意义不一样。sizeof引用得到的是所指向的变量的大小,而sizeof指针是对象地址的大小。
4. 指针和引用自增(++)自减(--)意义不一样。
5. 相对而言,引用比指针更安全。
总结一下:
指针比引用更灵活,但是也更危险。使用指针时一定要注意检查指针是否为空。指针所指的地址释放以后最好置0,否则可能存在野指针 问题。