我了解printf
,fprintf
,sprintf
等功能与vprintf
,vfprintf
,vsprintf
等功能之间的区别与他们如何处理函数参数有关。但具体怎么样?有没有理由使用一个而不是另一个?我是否应该始终使用printf
,因为这在C中更常见,或者是否有合理的理由选择vprintf
?
答案 0 :(得分:70)
printf()
和朋友正常使用。 vprintf()
和朋友们想要编写自己的printf()
类功能。假设您要编写一个函数来打印错误:
int error(char *fmt, ...)
{
int result;
va_list args;
va_start(args, fmt);
// what here?
va_end(args);
return result;
}
您会注意到您无法将args
传递给printf()
,因为printf()
需要多个参数,而不是一个va_list
参数。然而,vprintf()
函数做采用va_list
参数而不是可变数量的参数,所以这里是完成的版本:
int error(char *fmt, ...)
{
int result;
va_list args;
va_start(args, fmt);
fputs("Error: ", stderr);
result = vfprintf(stderr, fmt, args);
va_end(args);
return result;
}
答案 1 :(得分:15)
您永远不想直接使用vprintf()
,但是当您需要时,它会非常方便换printf()
。对于这些情况,您将使用变量参数(...)定义顶级函数。然后,您将这些内容收集到va_list
,进行处理,最后在vprintf()
上致电va_list
以获取打印输出。
答案 2 :(得分:0)
可变参数的主要困难不是存在可变数量的参数,而是没有与每个参数关联的名称。 va_start,va_arg宏使用格式字符串cf中包含的类型信息解析内存中的参数(在大多数C编译器中它们在堆栈中)。 Kernighan和Ritchie,第二版,第7.3节。
答案 3 :(得分:0)
此示例显示了Python的精美之处。由于C / C ++无法协调int error(char *fmt, ...)
和int error(char *fmt, va_list ap)
之间的差异,因此,对于每个函数*printf
,它都必须创建两个版本,即,一个版本接受...
,另一个使用va_list
,这实际上使功能总数增加了一倍。在Python中,您可以使用*list()
或**dict()
作为va_list
来传递...
。
希望将来的C / C ++可以支持这种参数处理方案。