C 程序中变量参数要求的澄清
我正在尝试协调我找到的在 C 中创建可变参数函数的规则。一方面,我看到明确说明的(例如, 此处)诸如“省略号之前始终是 int”之类的语句。另一方面,我看到很多示例程序,包括 stackoverflow 上的示例程序,它们都没有提及这样的规则(或约定),而且实际上没有它也可以工作。我看到许多其他形式(额外的 int),似乎也有效。 (事实上,最常见的函数似乎是这样定义的:int myFunc(char *format, ...) 并与 sprintf 或朋友一起使用)。
我试图理解它是如何工作的,以便未来的工作基于理解,而不是基于复制/粘贴的使用。目前,对我来说,它无异于一根魔杖。因此,为了了解如何充分利用该选项,我需要了解规则。您能否帮助我理解为什么我发现这些相互冲突的要求以及为什么这两种约定似乎都有效?
谢谢。
I'm trying to reconcile the rules I find for creating variadic functions in C. On the one hand I see explicitly stated (for example, here) statements like "just before the ellipses is always an int". On the other hand, I see lots of example programs, including on stackoverflow that make no mention of such a rule (or convention), and in fact work without it. And I see many of the other form (the extra int), that also seem to work. (The most common function, in fact seems to be one defined like: int myFunc(char *format, ...)
and is used with sprintf
or friends).
I'm trying to wrap my head around how it works so that future efforts are based upon understanding, rather than based on the use of copy/paste. At present, for me, it might as well be a magic wand. So in order to understand how to get the most out of the option, I need to understand the rules. Can you help me understand why I find such conflicting requirements and why both conventions seem to work?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
关于可变参数函数的主要规则是,您需要某种方法来确定您有多少参数以及这些参数的类型,尽管不一定是教程所说的方式。
一般来说,有两种方法:固定参数之一告诉您可变参数的数量和可能的类型,或者可变参数之一是指定参数列表末尾的标记值。
标准库和 POSIX 中的示例:
printf
和系列:第一个参数是格式字符串,该格式字符串的内容指定每个可变参数的数量和类型。execl
:两个固定参数中的第二个是要运行的外部程序的第一个参数。如果它不为 NULL,则可变参数将被读取为 const char * 类型,直到找到一个 NULL。第一个选项的变体如您所提到的:固定参数之一是可变参数的数量,其中每个可变参数具有相同的预定类型。这是最简单的实现方式,这可能就是您链接的教程建议它的原因。
您选择哪一个完全取决于您的用例。
另一个有趣的变化是 Linux 和类似系统上的
open
函数。手册页显示了以下签名:实际声明如下所示:
在本例中,如果
flags
参数包含值O_CREAT
,则读取一个可变参数。The main rule regarding a variadic function is that you need some way of determining how many arguments you have and what the type of those arguments are, though not necessarily the way the tutorial say.
Generally, there are two ways: either one of the fixed arguments tells you the number and possibly the type of the variadic arguments, or one of the variadic arguments is a sentinel value which specifies the end of the argument list.
Examples from the standard library and POSIX:
printf
and family: The first argument is a format string, and the contents of this format string specify the number and type of each variadic argument.execl
: The second of its two fixed arguments is the first argument of an external program to run. If it is not NULL, variadic arguments are read as typeconst char *
until it finds one that is NULL.A variation of the first option is as you mentioned: one of the fixed arguments is the number of variadic arguments, where each variadic argument has the same predetermined type. This is the simplest to implement, which is probably why the tutorial you linked suggested it.
Which of these you choose depends entirely on your use case.
Another interesting variation is the
open
function on Linux and similar systems. The man pages show the following signatures:The actual declaration looks something like this:
In this case, one variadic argument is read if the
flags
parameter includes the valueO_CREAT
.C 标准中没有规定函数声明中
...
之前的参数必须是int
。您链接到的文章仅引用其特定示例:当使用(int foo, ...)
声明函数时,第一个参数传递给该特定函数(在从任何实际参数是;例如,char
参数将转换为int
)始终是int
。一般来说,
...
之前的参数可以是任何类型。唯一的规则是...
之前必须至少有一个显式参数。There is no rule in the C standard that the parameter just before
...
in a function declaration must be anint
. The article you link to is merely referring to its particular example: When a function is declared with(int foo, ...)
, then the first argument passed to that specific function (after conversion from whatever the actual argument is; e.g., achar
argument will be converted toint
) is always anint
.In general, you can have any types for the parameters before
...
. The only rule is there must be at least one explicit parameter before the...
.