C/C++的参数传递机制

发表于:2015-1-19 10:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:飞鹤0755    来源:51Testing软件测试网采编

  近来公司招人较多,由此面试了非常多的C++程序员。面试时,我都会问到参数传递的相关问题,尤其侧重指针。因为指针毕竟是C/C++最重要的一个优势(在某种情况下也可以说是劣势)。但其结果是,1/3的人基本上讲错了,1/3的知其然却不知其所以然。所以我觉得有必要把这些知识点梳理下,分享出来。(下面的讨论都是基于VS和GCC的默认编译方式,其他特殊编译方式不在本文作用范围内。)
  C/C++函数参数的传递方式有三种:值传递(pass by value)、指针传递(pass bypointer)、引用传递(pass by reference)。
  C/C++函数参数的传递通道是通过堆栈传递,默认遵循__cdecl(C声明方式),参数由调用者从右往左逐个压入堆栈,在函数调用完成之后再由调用者恢复堆栈。(Win32API遵循stdcall传参规范的,不在本文讨论范围)
  下面是测试代码
void Swap(__int64* _pnX, __int64* _pnY)
{
__int64 nTemp = *_pnX;
*_pnX = *_pnY;
*_pnY = nTemp;
}
void Swap(__int64& _nX, __int64& _nY)
{
__int64 nTemp = _nX;
_nX = _nY;
_nY = nTemp;
}
void SetValue(__int64 _nX)
{
__int64 nTemp = _nX;
}
// Test001
void GetMemory(__int64* _pBuff)
{
_pBuff = new __int64[4];
}
// Test002
void GetMemory(__int64** _ppBuff)
{
*_ppBuff = new __int64[4];
}
int _tmain(int argc, _TCHAR* argv[])
{
__int64 nA = 0x10;
__int64 nB = 0x20;
// Test to pass by pointer
Swap(&nA, &nB);
// Test to pass by reference
Swap(nA, nB);
// Test to pass by value
SetValue(nA);
// Test the pointer that points the pointer
__int64* _pArray = NULL;
GetMemory(&_pArray);
delete[] _pArray;
_pArray = NULL;
// Test the pointer
GetMemory(_pArray);
return 0;
}
  指针传递和引用传递
// 下面看一下对应的反汇编的代码(VS版)
__int64 nA = 0x10;
0041370E  mov         dword ptr [nA],10h
00413715  mov         dword ptr [ebp-8],0
__int64 nB = 0x20;
0041371C  mov         dword ptr [nB],20h
00413723  mov         dword ptr [ebp-18h],0
// Test to pass by pointer
Swap(&nA, &nB);
0041372A  lea         eax,[nB]
0041372D  push        eax
0041372E  lea         ecx,[nA]
00413731  push        ecx
00413732  call        Swap (4111E5h)
00413737  add         esp,8
// Test to pass by reference
Swap(nA, nB);
0041373A  lea         eax,[nB]
0041373D  push        eax
0041373E  lea         ecx,[nA]
00413741  push        ecx
00413742  call        Swap (4111E0h)
00413747  add         esp,8
// GCC版
0x00401582 <+30>:    lea    eax,[esp+0x18]
0x00401586 <+34>:    mov    DWORD PTR [esp+0x4],eax
0x0040158a <+38>:    lea    eax,[esp+0x1c]
0x0040158e <+42>:    mov    DWORD PTR [esp],eax
0x00401591 <+45>:    call   0x401520 <Swap(int*, int*)>
0x00401596 <+50>:    lea    eax,[esp+0x18]
0x0040159a <+54>:    mov    DWORD PTR [esp+0x4],eax
0x0040159e <+58>:    lea    eax,[esp+0x1c]
0x004015a2 <+62>:    mov    DWORD PTR [esp],eax
0x004015a5 <+65>:    call   0x401542 <Swap(int&, int&)>
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号