指针 v.s. 引用

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

程序

先看一个小程序:

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

    printf("&a = %02X\n", &a); //3EFCD0<<
    printf("a = %d\n", a); //1
    printf("&ra = %02X\n", &ra); //3EFCD0<<
    printf("ra = %d\n", ra); //1
    printf("&pa = %02X\n", &pa); //3EFCB8
    printf("pa = %02X\n", pa); //3EFCD0<<
    printf("*pa = %d\n", *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\n", ra);

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

时间: 2024-12-28 14:59:47

指针 v.s. 引用的相关文章

值传递,指针传递;引用传递(c++独有)本质

要理解值传递.指针传递和引用传递的区别,主要要理解函数的实参和形参,函数的作用域(自动变量.栈),内存的布局以及指针和引用的特点.这里主要总结三种参数传递方式使用的主要场合. 值传递:只给函数提供输入值,需要复制开销,大对象很少使用值传递. 指针传递:可以改变指针指向内容的值,但是不能改变指针本身,无需复制开销.如果需要改变指针本身,可以使用二重指针或者指针引用. 引用传递:除了提供输入值外,还返回操作结果,无需复制开销. #include<stdlib.h> //值传递,函数体内变量n是参数

关于函数传参--传指针,传引用

今天和同学讨论到指针和引用的传递问题,有些想法从推理上讲是正确的,但是因为是推理,说出自己观点的时候不是那么有底气,本着实践是检验真理的唯一标准的原则,在电脑上敲了几段代码,验证了推理的正确性. 先上代码,再分析. 代码1: void Swap0(int a1,int b1){ int temp; temp=a1; a1=b1; b1=temp; } void Swap1(int *a1,int *b1){ //交换地址 int *temp; temp=a1; a1=b1; b1=a1; } v

c++智能指针以及循环引用问题(转)

解决循环引用: 在知道存在循环引用的条件下,使用boost::weak_ptr,即弱引用来代替循环引用中的某个强引用,从而打破循环引用的环. 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete,比如流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见,并造成内存泄露.如此c++引入 智能指针 . c++ 智能指针主要包括:unique_ptr,shared_ptr, weak_ptr, 这三种,其中auto

【转载】C++ 值传递、指针传递、引用传递详解

原文链接:http://www.cnblogs.com/yanlingyin/ 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入, 不能传出.当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递. 指针传递: 形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作 引用传递: 形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数

C++ 值传递、指针传递、引用传递详解

写在前头: 本文摘抄字博客:http://www.cnblogs.com/yanlingyin/archive/2011/12/07/2278961.html 自己的理解: 关于指针和引用的区别在于: 指针是对地址的一份拷贝,虽然对其的使用,可以通过地址来改变实参的值, 但如果对这个指针的拷贝,做出改变,那么这种改变将不影响实参. 而引用,是一种间接的操作,对形参的所有改变,都会通过间接的操作,映射到实参中,引用本身就是一种别名, 所以对这个别名的操作,就是对实参的操作. 还有一些其他的区别,就

C++函数的三种传递方式为:值传递、指针传递和引用传递

值传递: void fun(int x){ x += 5; //修改的只是y在栈中copy x,x只是y的一个副本,在内存中重新开辟的一块临时空间把y的值 送给了x:这样也增加了程序运行的时间,降低了程序的效率. } void main(void){ int y = 0; fun(y); cout<<\"y = \"<<y<<endl; //y = 0; } 指针传递: void fun(int *x){ *x += 5; //修改的是指针x指向的内

深入学习 const指针,const引用

指针和引用的区别: 1.指针可以为空,引用不可以为空. 2.指针初始化后可以重新指向新对象,引用初始化以为不可以重新绑定新对象, 3.指针可以在初始化时赋值,可以初始化以后通过赋值运算符(=)赋值:引用只能在初始化时赋值. 4.指针是个实体(占内存4byte),引用只是个别名(不占内存) 5.指针sizeof是4byte,引用sizeof是绑定对象的大小. 6.指针是类型安全,引用是类型安全的. const对于指针和引用的区别: int a = 1: int b = 1: const int *

C++中值传递、指针传递、引用传递的总结

C++中值传递.指针传递.引用传递的总结 指针传递和引用传递一般适用于:函数内部修改参数并且希望改动影响调用者.对比值传递,指针/引用传递可以将改变由形参"传给"实参(实际上就是直接在实参的内存上修改,不像值传递将实参的值拷贝到另外的内存地址中才修改).指针/引用传递的另外一种用法是:当一个函数实际需要返回多个值,而只能显式返回一个值时,可以将另外需要返回的变量以指针/引用传递给函数,这样在函数内部修改并且返回后,调用者可以拿到被修改过后的变量,也相当于一个隐式的返回值传递吧. 1.

【c++基础】const、const指针、const引用

一.const常量 声明时必须同时初始化(和“引用”一样) 二.const指针 三.const引用 引用本身和引用的对象都是const对象,可以用字面值来赋给const引用(普通引用则不行) 1 const B=1024; 2 const refB=B; //const变量的声明和初始化 3 4 const int &r=42;//字面值给const赋值 5 int &r2=42;//错 [c++基础]const.const指针.const引用