本文为原创,纯属本人理解,如有错误,请不吝指出。
最近遇到一个问题:
我写了一个函数,函数当中调用f(a),char a是在这个函数里面仅仅用作计算的,并不会改变a的值,这时有另外一个人说必须要f(&a)才更好。为了深入研究这个问题,我写了一些实验函数验证了一下。
环境在VC++ 6.0当中实验。
- void f(double a)
- {
- }
- void f2(double a[222])
- {
- }
- void f1(double* a)
- {
- }
- int main()
- {
- double a;
- double b;
- double c[200];
- f(a);
- f1(&b);
- f2(c);
- return 0;
- }
文中列举了a, b,c3中传参的方式,查看一下汇编下面的运行情况
- 19: f(a);
- 0040131E mov eax,dword ptr [ebp-4]
- 00401321 push eax
- 00401322 mov ecx,dword ptr [ebp-8]
- 00401325 push ecx
- 00401326 call @ILT+5(f) (0040100a)
- 0040132B add esp,8
上面的代码是指的是double a传参数的具体情况,首先把a的2个字节的内容放入eax寄存器当中,然后压入函数栈,然后把后2个直接的内容放入ecx寄存器当中,然后压入函数栈。
- 20: f1(&b);
- 0040132E lea edx,[ebp-10h]
- 00401331 push edx
- 00401332 call @ILT+0(f1) (00401005)
- 00401337 add esp,4
上面的代码指的是double b;的具体的传参数情况,将b的地址取出,存放到edx这个寄存器当中,然后压栈。
- 21: f2(c);
- 0040133A lea eax,[ebp-650h]
- 00401340 push eax
- 00401341 call @ILT+25(f2) (0040101e)
- 00401346 add esp,4
上面的代码指的是
double c[200]; 的具体的传参数情况,将c的地址取出,存放到edx这个寄存器当中,然后压栈。
第三种情况虽然c是个数组,里面有200个double类型的变量,但是传到函数当中的时候过程和第二种情况是一样的。
对于第一种情况,由于现在是double类型的变量,8个直接的,于是4个字节的寄存器无法一次存入,因此压栈的开销要大于第二,第三种情况。
但是如果第一种情况是一个char a类型的变量的话,那么这个压栈的过程就跟第2,第三种情况开销一致了。
所以说一开始的问题调用f(a)或者是f(&a)完全是可以的,另外,考虑当程序的可读性和安全性,个人还是推荐写f(a)比较好,这样a不会在函数里由于什么原因被修改掉。
阅读(1978) | 评论(1) | 转发(0) |