Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1856067
  • 博文数量: 343
  • 博客积分: 10342
  • 博客等级: 上将
  • 技术积分: 2892
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 12:34
个人简介

你必须非常努力,才能看起来毫不费力!

文章存档

2012年(3)

2011年(5)

2010年(2)

2009年(40)

2008年(293)

分类:

2008-10-06 12:48:53

我们先从比较熟悉的指针反汇编来分析,之后对比引用反汇编,看看他们的区别极其联系

8:        int ival=1024;

0040F5F8   mov         dword ptr [ebp-4],400h

9:        int &refVal=ival;

0040F5FF   lea         eax,[ebp-4]

0040F602   mov         dword ptr [ebp-8],eax

10:

11:       cout<

0040F605   push        2Ch

0040F607   mov         ecx,dword ptr [ebp-8]

0040F60A   mov         edx,dword ptr [ecx]

0040F60C   push        edx

0040F60D   mov         ecx,offset cout (00428ac0)

0040F612   call        ostream::operator<< (00401280)

0040F617   mov         ecx,eax

0040F619   call        @ILT+15(ostream::operator<<) (00401014)

12:       cout<<&refVal<<',';

0040F61E   push        2Ch

0040F620   mov         eax,dword ptr [ebp-8]

0040F623   push        eax

0040F624   mov         ecx,offset cout (00428ac0)

0040F629   call        ostream::operator<< (004011e0)

0040F62E   mov         ecx,eax

0040F630   call        @ILT+15(ostream::operator<<) (00401014)

13:

14:       int ival2=2048;

0040F635   mov         dword ptr [ebp-0Ch],800h//800h赋给[ebp-0Ch]这个地址对应的存储单元

 

15:       int *pointer=&ival2;

0040F63C   lea         ecx,[ebp-0Ch] //[ebp-0Ch]这个地址传给寄存器ecx

0040F63F   mov         dword ptr [ebp-10h],ecx//ecx的值传给[ebp-10h]对应的存储单元(:pointer)

16:

17:       cout<<*pointer<<',';

0040F642   push        2Ch

0040F644   mov         edx,dword ptr [ebp-10h] //pointer存储的地址值传给edx

0040F647   mov         eax,dword ptr [edx] //edx存储地址对应的值传给eax(:*pointer)

0040F649   push        eax//*pointer值入栈

0040F64A   mov         ecx,offset cout (00428ac0)

0040F64F   call        ostream::operator<< (00401280)

0040F654   mov         ecx,eax

0040F656   call        @ILT+15(ostream::operator<<) (00401014)

18:       cout<

0040F65B   push        2Ch

0040F65D   mov         ecx,dword ptr [ebp-10h] //pointer存储的地址值传给ecx

0040F660   push        ecx//pointer值入栈

0040F661   mov         ecx,offset cout (00428ac0)

0040F666   call        ostream::operator<< (004011e0)

0040F66B   mov         ecx,eax

0040F66D   call        @ILT+15(ostream::operator<<) (00401014)

 

运行结果:2048,0X0013FF74,1024,0X0013FF7C

之前,先说明下操作符”*”;C++预定义了一个饿专门的取地址(address-of)操作符(&).当我们把他应用在一个对象上时,返回的是对象的地址值.因此,为了将ival2地址值赋给pointer,我们这样写:

  int *pointer;

pointer=&ival;

为了访问pointer所指向的实际对象,我们必须先用解引用(dereference)操作符(*)来解除pointer的引用(dereference  pointer).我们暂且这样来认为这段程序:变量pointer引用(存放)了一个对象ival的地址,我们通过一把钥匙”*”来开启pointer地址对应房间的大门,从而进入这个房间.回到程序中,也就是说只要解引用+地址就能访问到对应内存单元.我们暂且认为解引用+地址=指针.因此,我个人认为指针这个概念因该是广义的.比如下面代码:

    int ival3=3096;

int &refVal=ival3;

cout<

这是所谓的关于引用类型的使用,&refVal是存放的ival3的地址.通用我们可以通过cout<<*(&refVal)<达到通用的结果.

 

 

从目前的代码来看,无论是指针pointer还是引用refVal,他们都是存放的所指对象的地址值.那么,他们是否就是一样的呢?引用和指针的区别在哪里?

我们知道,对于指针*pointer, 我们可以通过一个取地址操作符”&”将一个对象的地址赋给pointer,这样就可以改变指针所指的对象了.那么自然的引用是否也可以呢?

首先,我们可以通过&refVal来得到被引用对象ival的地址(int &refVal=ival,这就类似于通过pointer=&ival2得到对象的地址值一样).其次,问题的关键就在于我们是否可以像指针那样随意的修改引用本身(:像修改pointer中的地址那样修改&relVal中的地址值).不幸的是,我们无法通过任何C++语法像指针那样方便的修改被引用对象的地址值.

    因此,引用一旦被定义(必须先初始化),就再也无法随意更改指向其他对象,他们是绑定在一起了.

阅读(1264) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~