C++:引用详解

目录

引用

如何定义引用

&符

引用的语法规则:

引用的特点

引用的用处:

引用和const关系

 其他的引用形式:

 引用和指针的区别

语法规则上

汇编层面(机器代码)

如何使用引用 

内置类型

自定义类型:

引用

就是别名。比如有个同学叫张磊,给他取个外号叫张三石,这就是别名。

如何定义引用

类型 &引用变量名称=变量名称

&符

int &c=a,这里的&符不是取地址符,这里是引用。

&符的左边有一个类型,右边是一个变量名,我们称为引用。

&a此时为取地址符,&的右边是一个变量名。

引用的语法规则:

给a,b开辟空间,不给c开辟空间 。

a与c的地址是一样的

所谓的引用,就是对已有的一个变量起了一个别名

引用的特点

1.不能定义所谓的空引用,

2.定义引用时必须给与初始化。

3.引用没有二级引用,引用不分等级,没有引用的引用。

引用的用处:

交换:

无引用时:使用指针交换两个整型值

 有引用:引用作为形参代替指针

 引用时,没有空引用所以不需要判断,比指针安全,在调动函数时必须对行参的引用初始化。

引用和const关系

  

const加在引用的左边,const修饰的是引用本身,c是a的别名,不能通过c去改变a;下面的const修饰的是引用本身,系统将会把const忽略掉

 常变量必须用常引用,普通变量可以用普通引用引用(可读可改),也可以用常引用引用(只可读不可改)

 

常引用可以引用普通变量,可以引用常变量,可以引用字面变量 

无法取得地址称为右值,可以取地址的为左值,右值引用只能引用字面常量,右值引用不能引用左值。

 其他的引用形式:

引用可以引用变量,引用数组,引用指针

第一个引用是引用数组里的某个元素,cr引用是整个数组。br引用是错误的,是因为开辟20个空间,每个空间的类型是整型类型的引用,但引用没有空间,一个开空间一个不要空间,矛盾。没有定义数组,数组里是引用的概念。

指针的别名 

 

 引用和指针的区别

语法规则上

1.从语法规则上将,指针变量存储某个实例(变量或对象)的地址;引用是某个实例的别名。

2.程序为指针变量分配内存区域;而不为引用分配内存区域。

3.解引用是指针使用时要在前加“*”;引用可以直接使用;

4.指针变量的值可以发生改变,存储不同实例的地址;引用在定义时就被初始化,之后无法改变(不能是其他实例的引用)。

5.指针变量的值可以为空(NULL,nullptr);没有空引用。

6.指针变量作为形参时需要测试它的合法性(判空NULL);引用不需要判空;

7.对指针变量使用“sizeof”得到的是指针变量的大小,对引用变量使用“sizeof”得到的是变量的大小。

对于x86系统来说,运行结果如下:

8.理论上指针的级数没有限制;但引用只有一级。即不存在引用的引用,但可以有指针的指针。

9.++引用与++指针的效果不一样。

 就++操作而言:会使指针变量指向下一个实体(变量或对象)的地址;而不是改变所指实体(变量或对象)的内容。对引用的操作直接反应到所引用的实体(变量或对象)。也就是说,指针加等是指向下一个存储单元的地址,引用加等是对某一个引用的实体加等。

引用和指针的相同点不可以对函数中的局部变量或对象以引用或指针返回

原因:当在主函数中调动func_1时,给它开辟了空间,再将a的地址返回,但是当函数结束时分配给它的栈帧消失了;当我们调动func_2时,定义一个a,以引用返回它的别名,并不是返回a这个实体,但当func_2的空间消失后,引用也就消失了。

什么情况下能以指针或以引用的形式返回变量的生存期不受函数的影响。也就是说,当函数调用结束后,变量仍然活着。可以加个静态,成为静态变量,可以使变量活着。返回全局变量的引用或者返回全局变量也可以,或者以引用进也可以以引用出。

汇编层面(机器代码)

编译的时候发现(int& x)是引用,换成了星号(*)const;将int* ip=&x中的&去掉;将x=100中的x给了星号(*);又将int& b=a换成了int* const b =&a;fun(a)改成了fun(&a)。引用在编译过程中变成了一个指针,这个指针是自身为常性的指针,也就是说,我们一旦定义了int* const b=&a,我们的b指针永远指向a的地址,不能指向其他。在定义引用时必须初始化。当用a给x时,实际上是把a的地址给x,将引用转换为指针。

 底层汇编处:

 8:lea是取a变量的地址,将a变量的地址给b;7: lea是取a变量的地址,将a变量的地址给ip,这两种结构在编程汇编是没有差别的。9:对*ip赋值成100,把ip的值给eax,对eax所指向的空间赋值成64h;10:对b赋值成200,把b的值放到eax,对eax所指向的空间赋值成0C8h,就是200。

从底层上将,引用就是指针,是一个自身为常性的指针。

如何使用引用 

内置类型

int Add_Int(int x,int y)   //从内存中取数据,只需访问一次内存,
{
    return x+y;
}
int Add_Int_a(int& x,int& y)  //引用时,传进去实际上一个地址,因为底层引用是一个指针。在这里访问内存要访问两次,指针对他解引用
{
    return x+y;
}
int Add_Int_b(const int& x,const int& y)//情况和上面一样
{
    return x+y;
}
int main()
{
    int a=10,b=20;
    int c=0;
    c=Add_Int(a,b);
    cout<<c<<endl;
    return 0;
}

 对于内置类型来说,最好使用值传递方式,不需要进行引用。内置类型,如果希望形参要改变实参的值,就给出一个引用;如果形参不去改变实参的值,就传值不要穿引用。

自定义类型:

 

funa

funb

调动funa将s1给s ,s里面也有1,2……,空间开销非常大,将数据拷进去时间开销也比较大;如果以引用形式,s的地址就是58,就是s1这个结构体的别名,引用在底层上实际就是指针,我们只需要传递4个字节就可以。

能够用引用就不要用指针 ,对于内置类型最好是传值,如果要求形参改变实参,就定义成引用

  • 22
    点赞
  • 136
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值