假设函数f1
调用f2
,f2
调用f3
,最后调用f5
,每个函数都将一个参数“arg”传递给被调用者,如下所示:
f1(arg, ...) -> f2(arg, ...) -> f3(arg, ...) -> f4(arg, ...) -> f5(arg, ...)
另一种方式,使用全局“arg”,无需传递参数“arg”,如:
int arg = 5;
f1(...) -> f2(...) -> f3(...) -> f4(...) -> f5(...)
哪一个更好?或者有任何方法更有用吗?
答案 0 :(得分:2)
添加参数'arg'可以使您的函数独立并可重新输入,这可能是好的,例如,在多线程应用程序中。 对于许多函数使用一个全局变量可能会在某些内容更改队列中任意两个函数之间的全局变量值时导致错误,并且您将获得意外且无效的结果。
答案 1 :(得分:0)
在某些体系结构上,包括x86-64(full spec in pdf),前几个参数在寄存器中传递。因此,如果您始终在参数列表中的同一位置使用arg
,并且在所有函数中一致地使用它,则编译器可能会利用它将其保留在适当的寄存器中。
几乎所有ABI都使用寄存器作为函数的返回值;在某些ABI(例如ARM)中,这与第一个参数使用的寄存器相同。但不是在x86-64上:eax
用于返回值,rdi
或rcx
(取决于平台)用于第一个参数。无论如何,杂乱的寄存器在操纵堆栈方面远远不够昂贵,并且操纵堆栈也不是那么昂贵。
所以,就个人而言,我不担心开销。全局变量会让你陷入麻烦。
答案 2 :(得分:0)
当我传递几个参数时,我会引起注意。情况变得更糟:
f1(arg1, arg2, ...) -> f2(arg1, arg2, ...) -> f3(arg1, arg2, ...) -> f4(arg1, arg2, ...)
在这种情况下,定义一个结构并传递它的引用是有意义的:
struct MyParams
{
int arg1, arg2;
};
void f()
{
MyParams prms = { ... };
f1(prms, ...) -> f2(prms, ...) -> f3(prms, ...) -> f4(prms, ...)
}
我建议你避免使用任何全局变量。收益(如果有的话)不值得低估。