引用
概念:
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它 引用的变量共用同一块内存空间。
语法:类型& 引用变量名(对象名) = 引用实体;
比如一个人将一个临时使用的整形变量随便命名了个o你直呼难受你就可以通过引用来将o引用并用tmp来代替
int& tmp = o;即可
所以我们可以把tmp当做o的别名来使用
引用特性
一个变量可以有多个引用
引用一旦引用一个实体,再不能引用其他实体
值得说的是虽然我们引用表面传的是值但是其实我们真正传的是地址.
引用在定义时必须初始化
引用常数
引用不匹配类型时:
如使用int类型去引用double会怎样呢?
直接引用是不行的.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1NvtSJB-1652361941334)(…/…/…/AppData/Roaming/Typora/typora-user-images/image-20220511160334042.png)]
加上const就可以了并且经历的转换.
我们把这个运用到函数参数上就可以高效率的接收任意类型了.
当然这样的引用我们只有读的权限并不可写入.
话说为什么我们加入const就可以接收了呢?
这跟我们编译器的转换过程有关.
我们编译器在转换的时候会先创建一个空间来把被接受的值如上图是a,然后进行更改后再给我们的接收值(本例的ra)所以我们的ra接收的值本质上其实是一个常量, 所以要用const修饰.
可以看看ra地址的截图:
虽然引用的是a但是ra和a的地址并不相同而ra的地址其实就是常数10的地址.
使用场景
1.做参数
2.做返回值
当然这个真正的作用并不是上图,到后续会讲到的.
传值和传引用效率比较
#include<iostream> #include <time.h> using namespace std; struct A { int a[10000]; }; void TestFunc1(A a) {} void TestFunc2(A& a) {} void TestRefAndValue() { A a; // 以值作为函数参数 size_t begin1 = clock(); for (size_t i = 0; i < 10000; ++i) TestFunc1(a); size_t end1 = clock(); // 以引用作为函数参数 size_t begin2 = clock(); for (size_t i = 0; i < 10000; ++i) TestFunc2(a); size_t end2 = clock(); // 分别计算两个函数运行结束后的时间 cout << "TestFunc1(A)-time:" << end1 - begin1 << endl; cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl; } int main() { TestRefAndValue(); return 0; }
结果如下:
传引用完爆传参.