指针 v.s. 引用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针 v.s. 引用相关的知识,希望对你有一定的参考价值。

对C++的指针总觉得和引用差不多,其实还是挺有差别的。

程序

先看一个小程序:

    int a = 1;
    int& ra = a;
    int* pa = &ra;

    printf("&a = %02X
", &a); //3EFCD0<<
    printf("a = %d
", a); //1
    printf("&ra = %02X
", &ra); //3EFCD0<<
    printf("ra = %d
", ra); //1
    printf("&pa = %02X
", &pa); //3EFCB8
    printf("pa = %02X
", pa); //3EFCD0<<
    printf("*pa = %d
", *pa); //1

 

内存示意图

 技术分享

编译器的规则

计算机里面是一个城市,

城市里面有很多间房子,每个房子都有编号,每个房子里面会放具体的材料。

城市里面还有一个派出所,派出所里面有很多小盒子,每个小盒子都有编号,盒子里面放的就是城市里面的门牌号码。

程序员可以给房子盒子取名字,然后通过名字来得到他们。

房子:引用;盒子:指针;名字:变量名;门牌号,盒子编号:地址。

&得到门牌号或者盒子编号,*去到盒子里面找到门牌号,找到对应房子里面的东西。

 

程序编译成下面的故事

===注册===

程序员:这里有一个材料(1),帮忙找个房子放一下,

城市管理机构:找到一个门牌号(3EFCD0)的空房子,就用这个房子吧

程序员:好的,以后我就叫这个房子a吧

程序员:一个名字a还不够,我还想给他取个名字叫做ra,留着备用

程序员:申请一个派出所的盒子,

城市管理机构:找到一个编号为(3EFCB8)的空盒子,就用这盒子吧

程序员:好的,以后我就叫这个盒子pa吧

程序员:这个盒子里面放进刚才那个房子ra门牌号吧。(当然也可以告诉他们用a门牌号)

 

===使用===

程序员:告诉我房子a的编号

程序员:告诉我房子a里面装了什么

程序员:告诉我房子ra的编号

程序员:告诉我房子ra里面装了什么

程序员:告诉我盒子pa的编号

程序员:告诉我盒子pa里面装了什么(当然是那个门牌号)

程序员:告诉我盒子pa里面装门牌号码对应房子里面装了什么。

 

这样看来指针(盒子)和引用(房子)还是有挺大差别的吧。

 

潜规则:

让人讨厌的就是这些潜规则 -___-||,但是记住会更加安全。

  • 房子申请了必须放东西(引用必须初始化),否则城市管理机构不干(编译不过),所以永远不会存在空引用(对于C#er而言很难理解,C#的引用鉴于C++指针和引用之间),这样省去了null check,更加高效。
    int & ra; //error C2530: “ra”: 必须初始化引用

     

  • 盒子申请可以不放东西(盒子不值钱,编译没有问题),但是要小心,在使用盒子前要自己先把门牌号放进去(运行时有问题),否则就要看城市管理机构心情,他们不会帮你清理盒子。
    int * pa;//运行时,使用没有初始化的pa,会有这样的异常:读取位置 0xCCCCCCCC 时发生访问冲突。

 

Q&A

Q: int a;可以吗?

A: 编译没有问题,但是和指针一样的问题,这个时候房子申请到了, 你不放材料进去,不知道城市管理机构会放什么东西进去。所以总结而言:你申请东西的时候(房子或者盒子)的时候,最好初始化它,或者不要太久以后再去初始化,没有坏处的,兄弟。

 

Q: 房子一旦申请就不能改变(引用不能改变),盒子却可以改变里面放在房子门牌号,怎么理解?

A: 其实房子和盒子没有本质的区别(怎么又绕回来了@[email protected]),因为他们都是一种东西,当你关注房子的时候,房子和盒子不一样:房子不能变,盒子却很灵活;但是如果你站在房子角度看房子,站在盒子的角度看盒子,是一样的,盒子一旦申请盒子编号也是不能再改变了,盒子只能是那个盒子。换种说法吧,有些时候你可以吧盒子的编号放在另外的盒子里面,被放进去的盒子就是和房子一样的地位了。(指针的指针,忽然觉得还有好长的路...)

 

Q:下面输出是多少

int a = 1;
int& ra = a;
a = 2;

printf("ra = %d
", ra);

A: "ra = 2"//因为ra和a就是同一个房子的两个名字。

 

以上是关于指针 v.s. 引用的主要内容,如果未能解决你的问题,请参考以下文章

简单 v.s. 基础

PSAT V.S. PreACT

ECMAscript v.s. Javascript

Open Source v.s. Open Core

Java基础 | Java中引用与指针的关系

C++:取消引用指针