C 什么';printf和vprintf函数族之间的区别是什么?什么时候应该使用一个函数族而不是另一个函数族?
我理解C 什么';printf和vprintf函数族之间的区别是什么?什么时候应该使用一个函数族而不是另一个函数族?,c,C,我理解printf,fprintf,sprintf等函数与vprintf,vfprintf,vsprintf等函数之间的区别与它们如何处理函数参数有关。但具体如何?真的有什么理由用一个代替另一个吗?我应该一直使用printf,因为这在C语言中更常见,还是有合理的理由选择vprintf。对于这些情况,您将使用变量参数(…)定义顶级函数。然后,您将把它们收集到va_列表中,进行处理,最后在va_列表上调用vprintf(),以获得打印输出。printf()和朋友是正常使用的vprintf()当您想编
printf
,fprintf
,sprintf
等函数与vprintf
,vfprintf
,vsprintf
等函数之间的区别与它们如何处理函数参数有关。但具体如何?真的有什么理由用一个代替另一个吗?我应该一直使用printf
,因为这在C语言中更常见,还是有合理的理由选择vprintf
。对于这些情况,您将使用变量参数(…)定义顶级函数。然后,您将把它们收集到va_列表中,进行处理,最后在va_列表上调用vprintf()
,以获得打印输出。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_列表
参数,而不是数量可变的参数,因此以下是完整的版本:
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;
}
可变参数的主要困难不在于参数的数量可变,而在于没有与每个参数关联的名称。va_start、va_arg宏使用格式字符串中包含的类型信息解析内存中的参数(在大多数C编译器中,它们位于堆栈上)。参见Kernighan和Ritchie,第二版,第7.3节。此示例展示了Python的优雅。由于C/C++无法协调int error(char*fmt,…)
和int error(char*fmt,va_list ap)
之间的差异,因此,对于每个函数*printf
,它必须创建两个版本,即一个接受..
,另一个接受va_list
,这实际上是函数总数的两倍。在Python中,您可以使用*list()
或**dict()
将va_列表作为..
传递
希望未来的C/C++能够支持这种参数处理方案。当然,您需要一个类似于error()
的warn()
函数,但打印“Warning:”,因此您可以创建自己的vprintf()
样式函数:int-verror(char*prefix,char*fmt,va_-list-args)
和haveerror()
用“error:”调用它,用“Warning:”调用它。
用“Warning:”调用它,但这都是语义。该学习变量函数了!这个答案澄清了问题,谢谢。注:“v”代表“可变变量”。知道这一点有助于帮助我记住vprintf
函数是什么,因为提醒自己“v”代表什么也会提醒我这些函数是什么。这里有更多关于“可变函数”的信息:。我建议在您的问题中添加标签“printf”和“可变函数”。