C++中的指针和引用

基础概念复习

由于C++比较底层,能直接操作到内存,同时C++又可以进行面向对象的程序设计。因此C++中的“指针(Pointer)”和“引用(Reference)”这两个概念都比较重要。先对几个基本概念进行复习。

左值和右值

程序中最常见的可以说就是用=进行的赋值操作。而针对赋值操作,就有了左值和右值的概念:

  • 左值(lvalue)表示的是一个内存位置,往往是一个变量名称。既可以出现在=左边,也可以出现在=右边;
  • 右值(rvalue)则往往是具体存储在内存中的某个具体数值。可以出现在=右边,但不能出现在=左边。

int a = 100,表示将100这个右值,存储在了变量a所表示的占据4个字节的int类型的内存位置;而int b = a中,变量a为右值,变量b为左值。因此是取变量a所对应的具体数值,存储在变量b表示的int类型的内存位置。总而言之,C++中一个变量的名字,实际上对应了内存位置具体数值两个内容。如下图:
变量赋值

符号重温

一直以来就对C++中*&这种比较“非人类”的标记比较头疼,在这里再把这些符号再复习一遍,同时巩固一下对应的概念。

首先一定要区分这两个符号用在左值和右值上的区别:

  • *用在左值时,如用在定义变量的时候,表示定义了一个指针变量。如int *pt,定义了一个int类型的指针pt,该变量的具体数值为一个内存地址,以该地址为起点的4个字节表示一个整数;
  • *用在右值时,如用在指针变量前,表示解引用操作,即取变量数值所对应的地址上的具体数值。如int a = *pt,表示以指针变量pt数值对应的内存地址为起点,读取4个字节,解析出整数,将该整数的值赋值给变量a
  • &用在右值时,则表示取地址操作。如int a,则int *pt = &a则表示取变量a对应的int类型的地址,赋值给指针变量pt

上述三种用法可以用下图总结:
取地址赋值
但C++中还有一个特性就是引用。将&用在左值上,如在定义一个变量时加上&,则表示定义的是一个引用变量。引用变量必须要在定义的时候就初始化,使得该变量一开始就指向某个具体变量。实际上定义一个引用变量,就相当于将一个原有变量所对应的地址和数值新增了一个名称:
定义引用
如上图,定义指向a的引用ref,实际上就相当于在变量a对应的地址和数值上增加了一个名称。因此之后无论是修改a还是修改ref,对应地址上的数值均会发生改变:
修改引用

符号位置

在使用*定义指针,或&定义引用时,符号靠近类型还是靠近变量名都是可以的,如下面两句都是合法的:

int a = 100;
int* ptr1 = &a; 
int *ptr2 = &a;

但一定注意在一行定义多个变量时,每个变量名前是否加上符号,才代表该变量是否是指针或引用。如int *p, i,很明显p为整数指针,i为整数,即相当于int *p; int i;;而若写作int* p, i,仍然是p为整数指针,i为整数!若想要同时定义多个指针,应该使用int *a, *b, *c

比较地址和引用

最后,比较一下地址和引用的一些差别。首先按下图定义各种变量:
初始化
即分别定义并初始化了整数变量ab,二者明显对应的是不同地址的不同数值。之后int &ref = a定义了一个指向a的引用,即将a对应的内存和数值新增了一个名称ref。最后int *pt = &a,定义了一个指向a的指针pt。与引用ref不同,指针pt实际上占用了一块内存,只是这块内存存储的值是变量a对应的内存地址。因此对该指针解引用*pt实际上也就对应变量a,作为左值时表示对变量a重新赋值,作为右值时表示取变量a对应的值。

之后重新赋值引用ref = b
重新赋值引用
由于引用ref、变量a和指针的解引用*pt实际上指向同一地址,因此这些变量的值都会因此而改变。不过此时变量a只是在数值上与变量b相同,二者仍然占据了不同的内存。

之后重新赋值变量b
重新赋值b
如上所述,变量a与变量b二者仍然占据了不同的内存,因此重新赋值变量b也并不会影响到变量a,以及指向变量a的引用ref和指针pt

最后重新赋值指针pt
重新赋值指针
可见将之前指向a的指针修改为指向b,实际上也就是修改了指针变量pt对应的具体数值为变量b对应的地址。

总而言之,引用与指针的主要区别总结为如下几点:

  • 指针可以为空,但不存在空引用,引用必须连接到一块合法的内存。
  • 由上面一点容易推出,引用必须在定义的时候就被初始化。而指针可以在任何时候被初始化。
  • 引用被初始化后,也不能再重新指向另一个对象。而指针可以在任何时候被重新赋值,而指向到另一个对象。
  • 引用变量并不占据内存,仅仅相当于让同一块内存有了两个名字,修改任一个名字的值,都会影响到另一个,但两个名字指向的内存始终是同一个;而指针变量本身也要占据一块内存,占据内存的大小由操作系统的位数决定,32位系统占据4字节,64位系统占据8字节。因此指针变量也存储一个具体的数值,这个具体的数值就对应着该指针目前连接的变量的地址,可以随时改动。
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值