C 函数中的变量参数
Posted
技术标签:
【中文标题】C 函数中的变量参数【英文标题】:Variable arguments in C functions 【发布时间】:2017-10-20 11:01:56 【问题描述】:我读过关于可变参数函数“int func(int, ...)
”的文章。
这些函数的参数在哪里分配(堆栈或堆)?
因为我读到va_end()
宏释放了分配给va_list
的空间,所以“释放”这个词引起了我的注意。
注意:我知道常规函数会进入堆栈,但这种类型的函数很有趣,因为参数的数量是未知的。
我只想确定它不像没有预定义空间的数组;
最后我们使用malloc()
和free()
。
链接:https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm
【问题讨论】:
通常变量参数被压入堆栈,就像常规参数一样。您不必担心malloc
或free
。
我只是想确定它不像没有预定义空间的数组:数组总是有一个预定义的空间。
它有什么不同?
【参考方案1】:
c 本身并没有指定诸如“堆”或“堆栈”之类的东西,因此编程标准和可移植c,您应该更好地考虑c 标准的类别:静态、自动和动态存储。
尽管如此,在典型的实现中,“自动存储”转换为“堆栈用于它”。函数参数就是这种情况,可变参数函数也不例外。
va_end()
可能释放一些动态存储(通常:在堆上分配)的原因是va_arg()
宏通常需要一些上下文信息来查找 next 参数。 va_start()
将为该信息分配内存(而不是为参数本身)并以某种方式对其进行初始化,以便第一个 va_arg()
调用返回第一个可变参数。
请注意,va_start()
的实现没有有分配内存。 va_list
的定义方式可能是为所需的上下文信息提供空间。但这对作为程序员的你根本不感兴趣,所有va_*
的东西对你来说都是一个黑匣子,如果文档声明“调用@987654331 @当清理完成时”,你就这样做;)
【讨论】:
【参考方案2】:通常平台有一个调用约定。前几个参数进入寄存器,后面的参数进入堆栈。这对 C 代码本身是故意不透明的。 va_start 和 va_end 提供了一个围绕该调用约定的包装器,以允许您按索引而不是按名称顺序访问参数。
请注意,您不能在运行时构建 va_args 块。这是 C 不允许你做的少数几件事之一。您只能通过调用变量 args 函数来生成块。
还要注意,实际上变量 args 列表用于包装对 vsprintf() 的调用。您几乎不会发现它们在生产 C 代码中用于任何其他目的。
【讨论】:
以上是关于C 函数中的变量参数的主要内容,如果未能解决你的问题,请参考以下文章
使用 C/C++ 中的派生类成员变量将参数传递给 Base 构造函数
C语言基础:作用域规则(局部变量,全局变量,形式参数)全局变量与局部变量在内存中的区别初始化局部变量和全局变量
C语言的两个问题: 所有的递归程序均可以用非递归算法实现?递归函数中的形式参数是自动变量吗? c语言中