【转】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
结论 传引用==传指针,只不过在写代码上语法有些区别
写的有点乱,不过基本意思应该说清楚了,不对的地方还请指教。