我几天前参加了一次技术面试,有人问我 C编译器的implments如何使用可变数量的参数? 它如何通过堆栈?
有人知道或可以探讨这个吗?
谢谢, 丹
答案 0 :(得分:10)
据我所知,用C ......
调用函数按从右到左的顺序将参数压入堆栈。
调用者负责在执行被调用函数后从堆栈中删除参数。这可能正是因为调用者保证知道它在堆栈上放了多少个参数,而被调用的函数可能会错误。
P.S。: 调用约定通常是特定于实现的。我刚刚描述的内容被称为“cdecl”调用约定。将此与通常称为“stdcall”的调用约定进行对比,其中被调用函数负责从堆栈中删除其参数。因此,它不支持可变长度的参数列表。
P.P.S。:正如用户nategoose所评论的那样,我没有提到变量参数列表实际上是如何使用的。参见例如POSIX documentation for the <stdarg.h>
header了解更多信息。
答案 1 :(得分:7)
它使用va_宏实现它们 - 例如va_start。确切地说,这些宏所做的是实现定义 - 换句话说,它将从CPU架构到架构,从编译器到编译器。但是他们必须在C调用堆栈中玩弄技巧。通常,这将涉及将最后一个命名参数的地址作为基础,然后通过在此基础上执行指针算法来访问可变参数。
答案 2 :(得分:0)
到目前为止,你很难过在技术面试中得到这个问题,我会假设正确答案是:
调用者将显式参数推送到堆栈,计数变量参数和变量参数本身。然后,目标函数代码将负责根据传递的计数和它的堆栈地址弹出所有参数。
并添加一些想法,为什么将这些参数放在单独的数组中是不方便的。
答案 3 :(得分:-1)
查看va_start,va_arg和va_end。 Here有很多信息。