C++中的引用

引用是C++新引进的概念在C语言中是不存在的,接下里啊重点介绍引用。

说到引用首先得提一个概念:变量名,变量名是指上是一段连续储存空间的别名,算是一个标号,门牌号,程序中通过变量来申请并命名内存空间。通过变量的名字来使用内存空间。

1.引用的概念

引用:相当于一个变量的别名,相当于给这个变量的内存空间重新起了第二个名字。

用法:如下代码

[html]  view plain  copy
  1. int main()  
  2. {  
  3.     int a = 10;//定义变量a  
  4.     int &b = a;//这就是引用,b对a的引用,现在b和a是同一块内存空间,可用b来修改a的值  
  5.     b = 100;  
  6.     cout << a << endl;  
  7.     cout << b << endl;  
  8.     getchar();  
  9.     return 0;  
  10. }  

2.引用是属于c++的语法范畴

3.引用做函数参数

注意://普通引用在声明的时候必须用其他的变量初始化

           //但是引用做函数的参数的时候不用初始化


4.复杂数据类型做函数参数的引用

[html]  view plain  copy
  1. struct stu//定义结构体变量  
  2. {  
  3.     int a;  
  4. };  
  5. void fun1(stu *p)//指针参数,可以通过指针修改结构体的数据  
  6. {  
  7.     cout << p-><< endl;  
  8. }  
  9. void fun2(stu &p)//引用做参数,可以修改结构体的数据  
  10. {  
  11.     cout << p.a << endl;  
  12. }  
  13. void fun3(stu p)//变量名做参数,不能修改结构体的数据  
  14. {  
  15.     cout << p.a << endl;  
  16. }  
  17. int main()  
  18. {   
  19.     stu tl;  
  20.     tl.a = 10;  
  21.     fun1(&tl);//传过去结构体变量的地址  
  22.     fun2(tl);//p相当于tl的别名  
  23.     fun3(tl);//将tl内存中的数据复制一份传递过去  
  24.     getchar();  
  25.     return 0;  
  26. }  
5.引用的意义

//引用作为变量的别名而出现,在一些场合可以代替指针
//引用相对于指针有更好的可读性和实用性

比如上面的交换两个数的值,引用更加的简单。

6.引用的本质----C++编译器如何实现的引用

[html]  view plain  copy
  1. int a=10;  
  2. int &b=a;//必须初始化b  

①单独使用引用时必须初始化,类似于const int a=10,必须初始化一样,所以这里的b好像一个常量

a和b均是同一块内存空间的门牌号

②引用占内存空间吗?

请问这个结构体所占大小是多少?

[html]  view plain  copy
  1. struct stu  
  2. {  
  3.     char name[24];//24  
  4.     int a;//4  
  5.     int &b;//4  
  6.     int &c;//4  
  7. };  

经检验大小为36

由此可由推出int &b,int &c各占四个字节

再次验证

[html]  view plain  copy
  1. struct stu  
  2. {  
  3.     char name[24];//24  
  4.     int a;//4  
  5.     char &b;//4  
  6.     char &c;//4  
  7. };  
此结构体大小也为36,

所以可得引用所占的空间和指针变量很类似。

总上所述可以得结论:引用的本质就是char *const p;引用在C++内部实现是用常指针实现的,所以引用所占的内存空间和指针大小相同,引用会让人误认为说变量的别名,没有自己的储存空间,这是C++为了实用性做出的细节隐蔽


7.函数返回值是引用(引用当左值)

①当函数返回值为引用://若返回栈变量,则不能成为其他引用的初始化值,也不能作为左值使用

[html]  view plain  copy
  1. int fun1()  
  2. {  
  3.     int a ;  
  4.     a = 10;  
  5.     return a;  
  6. }  
  7. int &fun2()  
  8. {  
  9.     int a;  
  10.     a = 10;  
  11.     return a;  
  12. }  
  13. int *fun3()  
  14. {  
  15.     int a;  
  16.     a = 10;  
  17.     return &a;  
  18. }  
  19. int main()  
  20. {  
  21.     int a = fun1();//函数1调用完成后内存空间被析构,返回10,将这个值一般情况下放在寄存器中,在拿给a。  
  22.   
  23.     int b = fun2();//用变量取接返回的引用,函数2调用完成后返回内存的本身,  
  24.                       //即在栈中给a开辟的空间的副本,值是10,  
  25.                     //  如果你用变量去接它把10就扔给b没有问题。  
  26.                  
  27.     int &c = fun2();//用引用去接引用,相当于接住了返回回来的空间地址,  
  28.     printf("%d  %d  %d", a, b, c);//在打印的时候编译器发现c是一个引用,于是就替换成*c,  
  29.                                  //但是这块内存空间被清空了,所以*c找到的可能是乱码。  
  30.     getchar();  
  31.     return 0;  
  32. }  
输出a,b正常,c不确定。

  //若返回全局变量或者静态变量的话,便可以为其他引用的初始值,即可以做右值,也可以做左值

[html]  view plain  copy
  1. int &fun()  
  2. {  
  3.     static int a = 10;//静态变量的话  
  4.     a++;  
  5.     return a;  
  6. }  
  7. int main()  
  8. {  
  9.     int &b = fun();//完全可以没有任何问题  
  10.     return 0;  
  11. }  
下面演示一下函数当左值

[html]  view plain  copy
  1. int &fun()  
  2. {  
  3.     static int a = 10;  
  4.     a++;  
  5.     return a;  
  6. }  
  7. int main()  
  8. {  
  9.      fun()=10;//函数当左值没有任何问题  
  10.     return 0;  
  11. }  
8.指针的引用


9.常引用

//1.使用变量初始化const常引用

//2.使用字面量常量初始化const常引用

1.用变量区=去初始化

[html]  view plain  copy
  1. int a=10;  
  2. const int &b=a;//常引用,其作用是让变量a具有可读性,不能通过b去修改a的值  
2.用常量去初始化

[html]  view plain  copy
  1. int &m=10;  
这样合法吗?

答:不合法,因为10这个字面量没有内存空间无法引用,因为引用就是给内存空间起别名。

怎么使它合法呢?

[html]  view plain  copy
  1. const int  &m=10;  

这样就合法了

,有个问题:const  int  &m=10开辟内存吗?

我的理解是:const int &m=10;编译器这么理解int no_name=10;   const int &m=no_name;这个no_name是无形的你不可见,编译器自己做了这个工作使这句话通过

转自:https://blog.csdn.net/it_iverson/article/details/76832741

猜你喜欢

转载自blog.csdn.net/zxx2096/article/details/79888339