[英]what's the difference between the printf and vprintf function families, and when should I use one over the other?
我知道printf
、 fprintf
、 sprintf
等函數與vprintf
、 vfprintf
、 vsprintf
等函數之間的區別與它們如何處理函數參數有關。 但具體如何? 真的有任何理由使用一個而不是另一個嗎? 我應該總是使用printf
因為這在 C 中更常見,還是有正當理由選擇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_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;
}
您永遠不想直接使用vprintf()
,但是當您需要例如包裝printf()
時,它非常方便。 對於這些情況,您將使用可變參數 (...) 定義頂級函數。 然后將它們收集到va_list
,進行處理,最后在va_list
上調用vprintf()
以進行打印輸出。
可變參數的主要困難不在於參數的數量是可變的,而是沒有與每個參數相關聯的名稱。 va_start、va_arg 宏使用格式字符串 cf 中包含的類型信息解析內存中的參數(在大多數 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_list
作為...
傳遞。
希望未來的 C/C++ 可以支持這種參數處理方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.