【转】C++中传值,传指针和传引用区别

原文链接:http://lovemelovemydogs.blog.163.com/blog/static/9778560200721012092/

//////////////////////////////////////////////////////////

记得初学C++时看过某书说“引用”在C++中是不占任何空间的,

所以效率比指针高,当时看书就觉得奇怪,比32机的4字节地址空间

还小?我一直始终认为指针在编译为要机器代码在32机上是一样的4

字节地址,去年和以前的一个同事谈起此事,同事也抱着相同的观点,

我也没办法说服他,只有用一段程序来验证结果。

// RefAndPointerTest.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "iostream"

#include "windows.h"

//#include "winbase.h"

using namespace std;

void Test(double val1,double val2);

void TestRef(double &val1,double &val2);

void TestPointer(double *val1,double *val2);

int main(int argc, char* argv[])

{

double a = 1.5;

double b = 5.0;

DWORD dwStartTime;

DWORD dwEndTime;

dwStartTime= GetTickCount();

int i;

for(i=0;i<100000000;i++)

Test(a,b);

dwEndTime= GetTickCount();

cout << "\nTime1=" << dwEndTime - dwStartTime << endl;

dwStartTime= GetTickCount();

for(i=0;i<100000000;i++)

TestRef(a,b);

dwEndTime= GetTickCount();

cout << "\nTime2=" << dwEndTime - dwStartTime << endl;

dwStartTime= GetTickCount();

for(i=0;i<100000000;i++)

TestPointer(&a,&b);

dwEndTime= GetTickCount();

cout << "\nTime3=" << dwEndTime - dwStartTime << endl;

cin.get();

return 0;

}

void Test(double val1,double val2)

{

double val = val1 + val2;

}

void TestRef(double &val1,double &val2)

{

double val = val1 + val2;

}

void TestPointer(double *val1,double *val2)

{

double val = *val1 + *val2;

}

VC 8.0中Debug版运行结果有些混乱

23: for(i=0;i<100000000;i++)

24: Test(a,b);

29: for(i=0;i<100000000;i++)

30: TestRef(a,b);

35: for(i=0;i<100000000;i++)

36: TestPointer(&a,&b);

第一次 运行结果:

Time1=7704

Time2=10000

Time3=10000

第二次 运行结果:

Time1=7672

Time2=9953

Time3=9937

第三 运行结果:

Time1=7672

Time2=9953

Time3=9937

始终是传值速度最快,没有优化的结果有些怪

反汇编代码略,都是以内联函数的形式编译,因为浮点指令看不太懂:D

VC 8.0中Release版运行结果

第一次 运行结果:

Time1=0

Time2=0

Time3=0

第二次 运行结果:

Time1=0

Time2=0

Time3=0

第三次 运行结果:

Time1=0

Time2=0

Time3=0

Release反汇编代码 显示调用

23: for(i=0;i<100000000;i++)

24: Test(a,b);

29: for(i=0;i<100000000;i++)

30: TestRef(a,b);

35: for(i=0;i<100000000;i++)

36: TestPointer(&a,&b);

的代码被优化掉了,看来VC 8.0还是很智能的

14: int main(int argc, char* argv[])

15: {

00401000 55 push ebp

00401001 8B EC mov ebp,esp

00401003 83 E4 F8 and esp,0FFFFFFF8h

00401006 56 push esi //压入GetTickCount在内存中的地址

16: double a = 1.5;

17: double b = 5.0;

18: DWORD dwStartTime;

19: DWORD dwEndTime;

20:

21: dwStartTime= GetTickCount();

00401007 8B 35 00 20 40 00 mov esi,dword ptr [__imp__GetTickCount@0 (402000h)]

0040100D 57 push edi

0040100E FF D6 call esi

00401010 8B F8 mov edi,eax

22: int i;

23: for(i=0;i<100000000;i++)

24: Test(a,b);

25: dwEndTime= GetTickCount();

00401012 FF D6 call esi //直接调用GetTickCount在内存中的地址

//两个call 之间只有一句mov 另外两次调用也如此

26: cout << "\nTime1=" << dwEndTime - dwStartTime << endl;

00401014 8B 0D 38 20 40 00 mov ecx,dword ptr [__imp_std::endl (402038h)]

0040101A 8B 15 48 20 40 00 mov edx,dword ptr [__imp_std::cout (402048h)]

00401020 51 push ecx

00401021 2B C7 sub eax,edi

00401023 50 push eax

00401024 68 34 21 40 00 push offset string "\nTime1=" (402134h)

00401029 52 push edx

0040102A E8 C1 01 00 00 call std::operator<<<std::char_traits<char> > (4011F0h)

0040102F 83 C4 08 add esp,8

00401032 8B C8 mov ecx,eax

00401034 FF 15 44 20 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402044h)]

0040103A 8B C8 mov ecx,eax

0040103C FF 15 40 20 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]

27:

28: dwStartTime= GetTickCount();

00401042 FF D6 call esi

00401044 8B F8 mov edi,eax

29: for(i=0;i<100000000;i++)

30: TestRef(a,b);

31: dwEndTime= GetTickCount();

00401046 FF D6 call esi

32: cout << "\nTime2=" << dwEndTime - dwStartTime << endl;

00401048 8B 0D 38 20 40 00 mov ecx,dword ptr [__imp_std::endl (402038h)]

0040104E 8B 15 48 20 40 00 mov edx,dword ptr [__imp_std::cout (402048h)]

00401054 51 push ecx

00401055 2B C7 sub eax,edi

00401057 50 push eax

00401058 68 3C 21 40 00 push offset string "\nTime2=" (40213Ch)

0040105D 52 push edx

0040105E E8 8D 01 00 00 call std::operator<<<std::char_traits<char> > (4011F0h)

00401063 83 C4 08 add esp,8

00401066 8B C8 mov ecx,eax

00401068 FF 15 44 20 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402044h)]

0040106E 8B C8 mov ecx,eax

00401070 FF 15 40 20 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]

33:

34: dwStartTime= GetTickCount();

00401076 FF D6 call esi

00401078 8B F8 mov edi,eax

35: for(i=0;i<100000000;i++)

36: TestPointer(&a,&b);

37: dwEndTime= GetTickCount();

0040107A FF D6 call esi

38: cout << "\nTime3=" << dwEndTime - dwStartTime << endl;

0040107C 8B 0D 38 20 40 00 mov ecx,dword ptr [__imp_std::endl (402038h)]

00401082 8B 15 48 20 40 00 mov edx,dword ptr [__imp_std::cout (402048h)]

00401088 51 push ecx

00401089 2B C7 sub eax,edi

0040108B 50 push eax

0040108C 68 44 21 40 00 push offset string "\nTime3=" (402144h)

00401091 52 push edx

00401092 E8 59 01 00 00 call std::operator<<<std::char_traits<char> > (4011F0h)

00401097 83 C4 08 add esp,8

0040109A 8B C8 mov ecx,eax

0040109C FF 15 44 20 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402044h)]

004010A2 8B C8 mov ecx,eax

004010A4 FF 15 40 20 40 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]

39:

40: cin.get();

004010AA 8B 0D 4C 20 40 00 mov ecx,dword ptr [__imp_std::cin (40204Ch)]

004010B0 FF 15 68 20 40 00 call dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::get (402068h)]

41: return 0;

42: }

VC++6.0 DEBUG版结果

23: for(i=0;i<100000000;i++)

24: Test(a,b);

29: for(i=0;i<100000000;i++)

30: TestRef(a,b);

35: for(i=0;i<100000000;i++)

36: TestPointer(&a,&b);

第一次 运行结果:

Time1=4812

Time2=4657

Time3=4672

第二次 运行结果:

Time1=4797

Time2=4687

Time3=4687

第三 运行结果:

Time1=4782

Time2=4671

Time3=4657

基本可以断定传值最慢,慢的不多是未优化的结果

传值和传址的运行结果相差不多

传值  00401941------00401959 为4个push,4个mov 1个call 1个add 1个jmp 共11条反汇编指令

传引用 004019C6------004019D6 为2个push,2个lea 1个call 1个add 1个jmp 共7条反汇编指令

传指针 00401A43------00401A53 为2个push,2个lea 1个call 1个add 1个jmp 共7条反汇编指令

由此可见传引用与传指针在编译后的指令是一致的

致于与传值的11条指令相比时间上相差不多,我想是因为指令周期不同,lea调用内存应该是很慢

22: int i;

23: for(i=0;i<100000000;i++)

00401926 mov dword ptr [ebp-1Ch],0

0040192D jmp main+58h (00401938)

0040192F mov eax,dword ptr [ebp-1Ch]

00401932 add eax,1

00401935 mov dword ptr [ebp-1Ch],eax

00401938 cmp dword ptr [ebp-1Ch],5F5E100h

0040193F jge main+7Bh (0040195b)

24: Test(a,b);

00401941 mov ecx,dword ptr [ebp-0Ch]

00401944 push ecx

00401945 mov edx,dword ptr [ebp-10h]

00401948 push edx

00401949 mov eax,dword ptr [ebp-4]

0040194C push eax

0040194D mov ecx,dword ptr [ebp-8]

00401950 push ecx

00401951 call @ILT+690(Test) (004012b7)

00401956 add esp,10h

00401959 jmp main+4Fh (0040192f)

25: dwEndTime= GetTickCount();

0040195B mov esi,esp

0040195D call dword ptr [__imp__GetTickCount@0 (0047b18c)]

00401963 cmp esi,esp

00401965 call __chkesp (004082c0)

0040196A mov dword ptr [ebp-18h],eax

26: cout << "\nTime1=" << dwEndTime - dwStartTime << endl;

0040196D push offset @ILT+235(std::endl) (004010f0)

00401972 mov edx,dword ptr [ebp-18h]

00401975 sub edx,dword ptr [ebp-14h]

00401978 push edx

00401979 push offset string "\nTime1=" (0046d034)

0040197E push offset std::cout (00478a10)

00401983 call @ILT+780(std::operator<<) (00401311)

00401988 add esp,8

0040198B mov ecx,eax

0040198D call @ILT+305(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401136)

00401992 mov ecx,eax

00401994 call @ILT+595(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401258)

27:

28: dwStartTime= GetTickCount();

00401999 mov esi,esp

0040199B call dword ptr [__imp__GetTickCount@0 (0047b18c)]

004019A1 cmp esi,esp

004019A3 call __chkesp (004082c0)

004019A8 mov dword ptr [ebp-14h],eax

29: for(i=0;i<100000000;i++)

004019AB mov dword ptr [ebp-1Ch],0

004019B2 jmp main+0DDh (004019bd)

004019B4 mov eax,dword ptr [ebp-1Ch]

004019B7 add eax,1

004019BA mov dword ptr [ebp-1Ch],eax

004019BD cmp dword ptr [ebp-1Ch],5F5E100h

004019C4 jge main+0F8h (004019d8)

30: TestRef(a,b);

004019C6 lea ecx,[ebp-10h]

004019C9 push ecx

004019CA lea edx,[ebp-8]

004019CD push edx

004019CE call @ILT+270(TestRef) (00401113)

004019D3 add esp,8

004019D6 jmp main+0D4h (004019b4)

31: dwEndTime= GetTickCount();

004019D8 mov esi,esp

004019DA call dword ptr [__imp__GetTickCount@0 (0047b18c)]

004019E0 cmp esi,esp

004019E2 call __chkesp (004082c0)

004019E7 mov dword ptr [ebp-18h],eax

32: cout << "\nTime2=" << dwEndTime - dwStartTime << endl;

004019EA push offset @ILT+235(std::endl) (004010f0)

004019EF mov eax,dword ptr [ebp-18h]

004019F2 sub eax,dword ptr [ebp-14h]

004019F5 push eax

004019F6 push offset string "\nTime2=" (0046d028)

004019FB push offset std::cout (00478a10)

00401A00 call @ILT+780(std::operator<<) (00401311)

00401A05 add esp,8

00401A08 mov ecx,eax

00401A0A call @ILT+305(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401136)

00401A0F mov ecx,eax

00401A11 call @ILT+595(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401258)

33:

34: dwStartTime= GetTickCount();

00401A16 mov esi,esp

00401A18 call dword ptr [__imp__GetTickCount@0 (0047b18c)]

00401A1E cmp esi,esp

00401A20 call __chkesp (004082c0)

00401A25 mov dword ptr [ebp-14h],eax

35: for(i=0;i<100000000;i++)

00401A28 mov dword ptr [ebp-1Ch],0

00401A2F jmp main+15Ah (00401a3a)

00401A31 mov ecx,dword ptr [ebp-1Ch]

00401A34 add ecx,1

00401A37 mov dword ptr [ebp-1Ch],ecx

00401A3A cmp dword ptr [ebp-1Ch],5F5E100h

00401A41 jge main+175h (00401a55)

36: TestPointer(&a,&b);

00401A43 lea edx,[ebp-10h]

00401A46 push edx

00401A47 lea eax,[ebp-8]

00401A4A push eax

00401A4B call @ILT+720(TestPointer) (004012d5)

00401A50 add esp,8

00401A53 jmp main+151h (00401a31)

37: dwEndTime= GetTickCount();

00401A55 mov esi,esp

00401A57 call dword ptr [__imp__GetTickCount@0 (0047b18c)]

00401A5D cmp esi,esp

00401A5F call __chkesp (004082c0)

00401A64 mov dword ptr [ebp-18h],eax

38: cout << "\nTime3=" << dwEndTime - dwStartTime << endl;

00401A67 push offset @ILT+235(std::endl) (004010f0)

00401A6C mov ecx,dword ptr [ebp-18h]

00401A6F sub ecx,dword ptr [ebp-14h]

00401A72 push ecx

00401A73 push offset string "\nTime3=" (0046d01c)

00401A78 push offset std::cout (00478a10)

00401A7D call @ILT+780(std::operator<<) (00401311)

00401A82 add esp,8

00401A85 mov ecx,eax

00401A87 call @ILT+305(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401136)

00401A8C mov ecx,eax

00401A8E call @ILT+595(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401258)

VC++6.0 Release版结果

23: for(i=0;i<100000000;i++)

24: Test(a,b);

29: for(i=0;i<100000000;i++)

30: TestRef(a,b);

35: for(i=0;i<100000000;i++)

36: TestPointer(&a,&b);

第一次 运行结果:

Time1=640

Time2=563

Time3=547

第二次 运行结果:

Time1=640

Time2=547

Time3=532

第三次 运行结果:

Time1=656

Time2=531

Time3=547

以上结果表明Test(a,b)依然最慢

TestRef(a,b)、TestPointer(&a,&b)相差仍然不多

Release版使用w32dasw反汇编

请注意:

:00401938 817DE400E1F505 cmp dword ptr [ebp-1C], 05F5E100

:004019BD 817DE400E1F505 cmp dword ptr [ebp-1C], 05F5E100

:00401A3A 817DE400E1F505 cmp dword ptr [ebp-1C], 05F5E100

循环条件中的100000000==0x05F5E100

所以主要比交这些段之间的指令

传值  0040193F------00401959 为4个push,4个mov 1个call 1个add 1个jmp 共11条反汇编指令

传引用 004019C4------004019D6 为2个push,2个lea 1个call 1个add 1个jmp 共7条反汇编指令

传指针 00401A41------00401A53 为2个push,2个lea 1个call 1个add 1个jmp 共7条反汇编指令

和DEBUG版的指令形式一样,所以效率上应该是一致的

:004018E0 55 push ebp

:004018E1 8BEC mov ebp, esp

:004018E3 83EC5C sub esp, 0000005C

:004018E6 53 push ebx

:004018E7 56 push esi

:004018E8 57 push edi

:004018E9 8D7DA4 lea edi, dword ptr [ebp-5C]

:004018EC B917000000 mov ecx, 00000017

:004018F1 B8CCCCCCCC mov eax, CCCCCCCC

:004018F6 F3 repz

:004018F7 AB stosd

:004018F8 C745F800000000 mov [ebp-08], 00000000

:004018FF C745FC0000F83F mov [ebp-04], 3FF80000

:00401906 C745F000000000 mov [ebp-10], 00000000

:0040190D C745F400001440 mov [ebp-0C], 40140000

:00401914 8BF4 mov esi, esp

* Reference To: KERNEL32.GetTickCount, Ord:016Dh

|

:00401916 FF158CB14700 Call dword ptr [0047B18C]

:0040191C 3BF4 cmp esi, esp

:0040191E E89D690000 call 004082C0

:00401923 8945EC mov dword ptr [ebp-14], eax

:00401926 C745E400000000 mov [ebp-1C], 00000000

:0040192D EB09 jmp 00401938

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401959(U)

|

:0040192F 8B45E4 mov eax, dword ptr [ebp-1C]

:00401932 83C001 add eax, 00000001

:00401935 8945E4 mov dword ptr [ebp-1C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0040192D(U)

|

:00401938 817DE400E1F505 cmp dword ptr [ebp-1C], 05F5E100

:0040193F 7D1A jge 0040195B

:00401941 8B4DF4 mov ecx, dword ptr [ebp-0C]

:00401944 51 push ecx

:00401945 8B55F0 mov edx, dword ptr [ebp-10]

:00401948 52 push edx

:00401949 8B45FC mov eax, dword ptr [ebp-04]

:0040194C 50 push eax

:0040194D 8B4DF8 mov ecx, dword ptr [ebp-08]

:00401950 51 push ecx

:00401951 E861F9FFFF call 004012B7

:00401956 83C410 add esp, 00000010

:00401959 EBD4 jmp 0040192F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0040193F(C)

|

:0040195B 8BF4 mov esi, esp

* Reference To: KERNEL32.GetTickCount, Ord:016Dh

|

:0040195D FF158CB14700 Call dword ptr [0047B18C]

:00401963 3BF4 cmp esi, esp

:00401965 E856690000 call 004082C0

:0040196A 8945E8 mov dword ptr [ebp-18], eax

:0040196D 68F0104000 push 004010F0

:00401972 8B55E8 mov edx, dword ptr [ebp-18]

:00401975 2B55EC sub edx, dword ptr [ebp-14]

:00401978 52 push edx

:00401979 6834D04600 push 0046D034

:0040197E 68108A4700 push 00478A10

:00401983 E889F9FFFF call 00401311

:00401988 83C408 add esp, 00000008

:0040198B 8BC8 mov ecx, eax

:0040198D E8A4F7FFFF call 00401136

:00401992 8BC8 mov ecx, eax

:00401994 E8BFF8FFFF call 00401258

:00401999 8BF4 mov esi, esp

* Reference To: KERNEL32.GetTickCount, Ord:016Dh

|

:0040199B FF158CB14700 Call dword ptr [0047B18C]

:004019A1 3BF4 cmp esi, esp

:004019A3 E818690000 call 004082C0

:004019A8 8945EC mov dword ptr [ebp-14], eax

:004019AB C745E400000000 mov [ebp-1C], 00000000

:004019B2 EB09 jmp 004019BD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004019D6(U)

|

:004019B4 8B45E4 mov eax, dword ptr [ebp-1C]

:004019B7 83C001 add eax, 00000001

:004019BA 8945E4 mov dword ptr [ebp-1C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004019B2(U)

|

:004019BD 817DE400E1F505 cmp dword ptr [ebp-1C], 05F5E100

:004019C4 7D12 jge 004019D8

:004019C6 8D4DF0 lea ecx, dword ptr [ebp-10]

:004019C9 51 push ecx

:004019CA 8D55F8 lea edx, dword ptr [ebp-08]

:004019CD 52 push edx

:004019CE E840F7FFFF call 00401113

:004019D3 83C408 add esp, 00000008

:004019D6 EBDC jmp 004019B4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004019C4(C)

|

:004019D8 8BF4 mov esi, esp

* Reference To: KERNEL32.GetTickCount, Ord:016Dh

|

:004019DA FF158CB14700 Call dword ptr [0047B18C]

:004019E0 3BF4 cmp esi, esp

:004019E2 E8D9680000 call 004082C0

:004019E7 8945E8 mov dword ptr [ebp-18], eax

:004019EA 68F0104000 push 004010F0

:004019EF 8B45E8 mov eax, dword ptr [ebp-18]

:004019F2 2B45EC sub eax, dword ptr [ebp-14]

:004019F5 50 push eax

:004019F6 6828D04600 push 0046D028

:004019FB 68108A4700 push 00478A10

:00401A00 E80CF9FFFF call 00401311

:00401A05 83C408 add esp, 00000008

:00401A08 8BC8 mov ecx, eax

:00401A0A E827F7FFFF call 00401136

:00401A0F 8BC8 mov ecx, eax

:00401A11 E842F8FFFF call 00401258

:00401A16 8BF4 mov esi, esp

* Reference To: KERNEL32.GetTickCount, Ord:016Dh

|

:00401A18 FF158CB14700 Call dword ptr [0047B18C]

:00401A1E 3BF4 cmp esi, esp

:00401A20 E89B680000 call 004082C0

:00401A25 8945EC mov dword ptr [ebp-14], eax

:00401A28 C745E400000000 mov [ebp-1C], 00000000

:00401A2F EB09 jmp 00401A3A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401A53(U)

|

:00401A31 8B4DE4 mov ecx, dword ptr [ebp-1C]

:00401A34 83C101 add ecx, 00000001

:00401A37 894DE4 mov dword ptr [ebp-1C], ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401A2F(U)

|

:00401A3A 817DE400E1F505 cmp dword ptr [ebp-1C], 05F5E100

:00401A41 7D12 jge 00401A55

:00401A43 8D55F0 lea edx, dword ptr [ebp-10]

:00401A46 52 push edx

:00401A47 8D45F8 lea eax, dword ptr [ebp-08]

:00401A4A 50 push eax

:00401A4B E885F8FFFF call 004012D5

:00401A50 83C408 add esp, 00000008

:00401A53 EBDC jmp 00401A31

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00401A41(C)

|

:00401A55 8BF4 mov esi, esp

* Reference To: KERNEL32.GetTickCount, Ord:016Dh

|

:00401A57 FF158CB14700 Call dword ptr [0047B18C]

:00401A5D 3BF4 cmp esi, esp

:00401A5F E85C680000 call 004082C0

:00401A64 8945E8 mov dword ptr [ebp-18], eax

:00401A67 68F0104000 push 004010F0

:00401A6C 8B4DE8 mov ecx, dword ptr [ebp-18]

:00401A6F 2B4DEC sub ecx, dword ptr [ebp-14]

:00401A72 51 push ecx

:00401A73 681CD04600 push 0046D01C

:00401A78 68108A4700 push 00478A10

:00401A7D E88FF8FFFF call 00401311

:00401A82 83C408 add esp, 00000008

:00401A85 8BC8 mov ecx, eax

:00401A87 E8AAF6FFFF call 00401136

:00401A8C 8BC8 mov ecx, eax

:00401A8E E8C5F7FFFF call 00401258

:00401A93 B9A08A4700 mov ecx, 00478AA0

:00401A98 E8D0F6FFFF call 0040116D

:00401A9D 33C0 xor eax, eax

:00401A9F 5F pop edi

:00401AA0 5E pop esi

:00401AA1 5B pop ebx

:00401AA2 83C45C add esp, 0000005C

:00401AA5 3BEC cmp ebp, esp

:00401AA7 E814680000 call 004082C0

:00401AAC 8BE5 mov esp, ebp

:00401AAE 5D pop ebp

:00401AAF C3 ret

结论 传引用==传指针,只不过在写代码上语法有些区别

写的有点乱,不过基本意思应该说清楚了,不对的地方还请指教。