簡體   English   中英

printf 和 vprintf 函數系列之間有什么區別,我應該什么時候使用一個?

[英]what's the difference between the printf and vprintf function families, and when should I use one over the other?

我知道printffprintfsprintf等函數與vprintfvfprintfvsprintf等函數之間的區別與它們如何處理函數參數有關。 但具體如何? 真的有任何理由使用一個而不是另一個嗎? 我應該總是使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM