Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 什么';printf和vprintf函数族之间的区别是什么?什么时候应该使用一个函数族而不是另一个函数族?_C - Fatal编程技术网

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)
和have
error()
用“error:”调用它,用“Warning:”调用它。
用“Warning:”调用它,但这都是语义。该学习变量函数了!这个答案澄清了问题,谢谢。注:“v”代表“可变变量”。知道这一点有助于帮助我记住
vprintf
函数是什么,因为提醒自己“v”代表什么也会提醒我这些函数是什么。这里有更多关于“可变函数”的信息:。我建议在您的问题中添加标签“printf”和“可变函数”。