c - 如何确定 va_arg 列表的结尾?

标签 c variadic-functions

我有一个函数 foo(char *n, ...); 我需要获取并使用所有可选的 char 参数。 我有一个想法可以使用

while(va_arg(argPtr, char) != NULL)
{
   ...
}

了解我何时到达列表末尾。那么,它会起作用吗,如果在函数调用中我会做 foo(n, 't', 'm', '$', NULL);

NULL 会被 va_arg 读取为 char 吗? 或者也许有一种更常见的方法来确定列表的结尾,而无需添加 NULL 作为最后一个参数?

最佳答案

对于使用 va_arg 的函数,没有直接方法来确定给定调用传递的参数的数量或类型。

特别是您提出的方法:

while(va_arg(argPtr, char) != NULL)

不正确。 va_arg(argPtr, char) 产生一个 char 类型的值,而 NULL 是一个空指针常量。 (NULL 通常定义为 0,比较等于空字符 '\0',但您不能依赖它。 )

任何可变参数函数都必须有一种方法供调用者指定参数的数量和类型。例如,*printf 函数通过(非可变参数)格式字符串执行此操作。 POSIX execl*() 函数需要一系列 char* 参数;参数列表的末尾由调用者用 (char*)NULL 标记。其他方法也是可能的,但它们几乎都依赖于运行时参数中给出的信息。 (您可以使用一些其他方法,例如全局变量。请不要。)

这会给调用者带来负担,以确保传递给函数的参数是一致的。函数本身无法确认这一点。不正确的调用,如 printf("%d\n", "hello")execlp("name", "arg1")未定义的行为.

还有一件事:您不能将 va_argchar 类型的参数一起使用。当您调用可变参数函数时,、... 对应的参数将被提升。类型小于 int 的整数参数被提升为 intunsigned int,类型为 float 的参数是提升为 double。如果调用方传递类型为 char 的参数,则该函数必须调用 va_arg(argPtr, int)

(在您不太可能遇到的非常晦涩的情况下,char 可以提升为 unsigned int。只有当纯 char 是无符号的并且 sizeof (int) == 1,这意味着一个字节至少是 16 位。)

关于c - 如何确定 va_arg 列表的结尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37356030/

相关文章:

c - 如何打印当前时间和日期

c++ - va_arg 中的转换方式

c - 单击后如何删除文本?

c - 我怎么能初始化一个分配了零字节的指针呢?

c - 如何使用 ## 运算符通过宏扩展生成字符串或字符常量

c - 如何知道我的参数是 char 还是带有 varargs 的 char*

使用 va_list 调用 printf

c - 将指针传递给指向 C 结构的指针数组

c - 在 C 中使用数组作为函数参数(反向可变参数)

C++11 可变参数 Printf 性能