这个题目最初是学弟问我的.很认真的和学弟一起讨论了这个问题,最终得到这一篇文章(ps但是当时还真是吓了一跳,发现学弟的水平真是日进千里,已经开始考虑底层(汇编相关的东西).)
关于指针与引用的区别网上有很多好的文章,比如这一篇:
http://blog.youkuaiyun.com/dujiangyan101/article/details/2844138
从概念上讲。指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。
而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。这二者起码在表意上是不同.
然而在VS环境下,进行反汇编,却会发现二者的实现是有共同之处.
源代码:
#include<stdio.h>
int main()
{
int m_int = 0;
int* m_ptr = &m_int;
int& m_ref = m_int;
}
生成的汇编代码:
#include<stdio.h>
int main()
{
012A13B0 push ebp
012A13B1 mov ebp,esp
012A13B3 sub esp,0E8h
012A13B9 push ebx
012A13BA push esi
012A13BB push edi
012A13BC lea edi,[ebp-0E8h]
012A13C2 mov ecx,3Ah
012A13C7 mov eax,0CCCCCCCCh
012A13CC rep stos dword ptr es:[edi]
012A13CE mov eax,dword ptr ds:[012A8000h]
012A13D3 xor eax,ebp
012A13D5 mov dword ptr [ebp-4],eax
int m_int = 0;
012A13D8 mov dword ptr [m_int],0
int* m_ptr = &m_int;
012A13DF lea eax,[m_int]
012A13E2 mov dword ptr [m_ptr],eax
int& m_ref = m_int;
012A13E5 lea eax,[m_int]
012A13E8 mov dword ptr [m_ref],eax
}
从上面的代码可以看出无论引用还是指针在定义初始化阶段都采用一样的汇编代码来实现的:
lea eax,[m_int]
mov dword ptr [m_ref],eax
代码简单易懂,就是贱m_int的(偏移)地址存放到对应的指针/引用的内存中,
从上面我们可以的出一个结论,引用于指针二者在实现上是类似的.
查询了相关的资料,我得出一个结论那就是引用是一个常量指针.然而这一切都只是编译器这么做,因为在C99的文档里是没有要求别名要这么实现,编译器这么做是可行的,(关于编译器与文档之间也有很多有趣的话题,等以后有机会再接着写一写文章),但是编译器屏蔽了引用和指针的差别。
以上的内容都是在VC/VS编译环境中,实现的.我在网上还找到了在gcc上讨论这二者的文章
http://my.oschina.net/fergus/blog/123490
但是我们依旧要明确,引用就是引用,虽然在实现上是采用指针的技术,但是由于编译器的作用,引用与指针有着巨大的不同,这一点还是要明确的,
最后,感谢亲爱的逆袭同学(可惜他不会看这篇文章,嘿嘿)