【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        ebp
00401051 8B EC                mov         ebp,esp
00401053 83 EC 44             sub         esp,44h
00401056 53                   push        ebx
00401057 56                   push        esi
00401058 57                   push        edi
00401059 8D 7D BC             lea         edi,[ebp-44h]
0040105C B9 11 00 00 00       mov         ecx,11h
00401061 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00401066 F3 AB                rep stos    dword ptr [edi]

再者,三者的调用细节:

;//传值
00401106 8B 45 F8             mov         eax,dword ptr [ebp-8]
00401109 50                   push        eax
0040110A 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040110D 51                   push        ecx
0040110E 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        ecx
00401157 8D 55 FC             lea         edx,[ebp-4]
0040115A 52                   push        edx
0040115B 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        eax
0040111A 8D 4D FC             lea         ecx,[ebp-4]
0040111D 51                   push        ecx
0040111E 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],ecx

7:        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++代码出来的指令竟然是一样的!

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

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

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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值