当前位置: 代码迷 >> C++ >> 【C/C++】C++中一些简单被人忽略的东西 之一 【寥寥代码,让您分清引用和指针】
  详细解决方案

【C/C++】C++中一些简单被人忽略的东西 之一 【寥寥代码,让您分清引用和指针】

热度:1462   发布时间:2013-02-26 00:00:00.0
【C/C++】C++中一些容易被人忽略的东西 之一 【寥寥代码,让您分清引用和指针】

转载请注明出处

由于阅历有限,篇幅不周之处还望指出,谢谢


千言万语不如一行代码,无声胜有声


#include <stdio.h>#include <iostream.h>void Xswap(int & x, int & y){	int temp=x;	x=y;	y=temp;}void Xswap(int * x,int *y){	int temp=*x;	*x=*y;	*y=temp;}void main(){	int a=10, b=20;	Xswap(a,b);				//传引用	cout<<"a="<<a<<"     b="<<b<<endl;	Xswap(&a,&b);			//传指针	cout<<"a="<<a<<"     b="<<b<<endl;	cin.get();}
输出:

另有:

#include <stdio.h>#include <iostream.h>void Xswap(int * x,int *y){	int temp=*x;	*x=*y;	*y=temp;}void Xswap(int x,int y){	int temp=x;	x=y;	y=temp;}void main(){	int a=10, b=20;	Xswap(a,b);				//传值	cout<<"a="<<a<<"     b="<<b<<endl;	Xswap(&a,&b);			//传指针	cout<<"a="<<a<<"     b="<<b<<endl;	cin.get();}
输出:



可见,同样的代码,玄机就在这"引用"上了。

引用实际上是已经声明变量的某一个别名。

引用和被引用的对象实际上是占用相同的内存单元。


为什么要有引用呢?

一般Xswap(a,b)是传值调用。

Xswap(&a,&b)是传地址调用。

那么当我们既不希望传值,也不希望通过指针这么"危险"的东西来调用的时候,就可以通过引用来。


再来看看三者的内存形态(内容过于血腥残暴,悠着点)~

首先,值得认同的是,三者的函数入口都是一样的:

;pointer & value & reference 00401050 55                   push        ebp00401051 8B EC                mov         ebp,esp00401053 83 EC 44             sub         esp,44h00401056 53                   push        ebx00401057 56                   push        esi00401058 57                   push        edi00401059 8D 7D BC             lea         edi,[ebp-44h]0040105C B9 11 00 00 00       mov         ecx,11h00401061 B8 CC CC CC CC       mov         eax,0CCCCCCCCh00401066 F3 AB                rep stos    dword ptr [edi]
再者,三者的调用细节:

;//传值00401106 8B 45 F8             mov         eax,dword ptr [ebp-8]00401109 50                   push        eax0040110A 8B 4D FC             mov         ecx,dword ptr [ebp-4]0040110D 51                   push        ecx0040110E E8 06 FF FF FF       call        @ILT+20(Xswap) (00401019)00401113 83 C4 08             add         esp,8
;//传指针00401153 8D 4D F8             lea         ecx,[ebp-8]00401156 51                   push        ecx00401157 8D 55 FC             lea         edx,[ebp-4]0040115A 52                   push        edx0040115B E8 B4 FE FF FF       call        @ILT+15(Xswap) (00401014)00401160 83 C4 08             add         esp,8
;//传引用00401116 8D 45 F8             lea         eax,[ebp-8]00401119 50                   push        eax0040111A 8D 4D FC             lea         ecx,[ebp-4]0040111D 51                   push        ecx0040111E E8 EC FE FF FF       call        @ILT+10(Xswap) (0040100f)00401123 83 C4 08             add         esp,8

因而,指针和引用其实就是一回事。

那为何他们使用的方法又有差别呢?

看下这两段小插曲~我想你一定能够明白!

14:       int temp=*x;004010B8 8B 45 08             mov         eax,dword ptr [ebp+8]004010BB 8B 08                mov         ecx,dword ptr [eax]004010BD 89 4D FC             mov         dword ptr [ebp-4],ecx7:        int temp=x;00401068 8B 45 08             mov         eax,dword ptr [ebp+8]0040106B 8B 08                mov         ecx,dword ptr [eax]0040106D 89 4D FC             mov         dword ptr [ebp-4],ecx

不同的C++代码出来的指令竟然是一样的!

原来"猫腻"就在编译器!

你给人家传引用,人家就把你代码按引用来翻译,你传的地址,人家就按地址来翻译。

回头想想,真觉得自己这是在故弄玄虚,既然两行代码干的事同一件事,编译出来的指令怎么可能不一样的呢?呵呵~



  相关解决方案