Ich verstehe, dass der Unterschied zwischen der printf
, fprintf
, sprintf
etc Funktionen und die vprintf
, vfprintf
, vsprintf
etc Funktionen hat damit zu tun, wie sie mit den Funktionsargumenten umgehen. Aber wie konkret? Gibt es wirklich einen Grund, einen über dem anderen zu verwenden? Soll ich einfach immer verwenden printf
da dies in C häufiger zu sehen ist, oder gibt es einen legitimen Grund für die Auswahl vprintf
stattdessen?
Was ist der Unterschied zwischen den Funktionsfamilien printf und vprintf, und wann sollte ich sie übereinander verwenden?
printf()
und Freunde sind für den normalen Gebrauch. vprintf()
und Freunde sind dafür da, wenn Sie Ihre eigenen schreiben möchten printf()
-ähnliche Funktion. Angenommen, Sie möchten eine Funktion zum Drucken von Fehlern schreiben:
int error(char *fmt, ...)
{
int result;
va_list args;
va_start(args, fmt);
// what here?
va_end(args);
return result;
}
Sie werden feststellen, dass Sie nicht bestehen können args
zu printf()
seit printf()
nimmt viele Argumente statt eines va_list
Streit. Das vprintf()
Funktionen, jedoch tun nimm ein va_list
Argument anstelle einer variablen Anzahl von Argumenten, also hier die fertige Version:
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;
}
-
Natürlich wollen Sie dann a
warn()
Funktion, die wie funktionierterror()
aber druckt stattdessen “Warnung: “, also erstellen Sie Ihre besitzenvprintf()
Style-Funktion:int verror(char *prefix, char *fmt, va_list args);
und habenerror()
rufe das mit “Error:” auf undwarn()
Nennen Sie es mit “Warnung: “, aber es ist alles Semantik.– Chris Lutz
28. September 2009 um 7:20 Uhr
-
Zeit, mehr über variadische Funktionen zu lernen! Diese Antwort hat die Dinge geklärt, danke.
– Carson Myers
28. September 2009 um 7:43 Uhr
-
Hinweis: Das ‘v’ steht für “variadic”. Das zu wissen ist nützlich, um mir zu helfen, mich daran zu erinnern, was das ist
vprintf
Funktionen sind es sogar, denn wenn ich mich daran erinnere, wofür das ‘v’ steht, erinnert mich das auch daran, wofür diese Funktionen sind. Mehr zu “variadic” hier: en.wikipedia.org/wiki/Variadic_function.– Gabriel Staples
12. Januar 2019 um 6:53 Uhr
Sie möchten nie verwenden vprintf()
direkt, aber es ist unglaublich praktisch, wenn Sie zB wickeln müssen printf()
. Für diese Fälle definieren Sie die Top-Level-Funktion mit variablen Argumenten (…). Dann sammelst du diese in a va_list
führen Sie Ihre Verarbeitung durch und rufen Sie schließlich an vprintf()
auf der va_list
um den Ausdruck zu erhalten.
-
Sag niemals nie.
– einpoklum
6. August 2021 um 19:58 Uhr
Die Hauptschwierigkeit bei variadischen Argumenten besteht nicht darin, dass es eine variable Anzahl von Argumenten gibt, sondern dass jedem Argument kein Name zugeordnet ist. Die Makros va_start, va_arg parsen die Argumente im Speicher (bei den meisten C-Compilern befinden sie sich auf dem Stack) unter Verwendung der Typinformationen, die in der Formatzeichenfolge cf enthalten sind. Kernighan und Ritchie, zweite Ausgabe, Abschnitt 7.3.
Dieses Beispiel zeigt die Eleganz von Python. Da C/C++ den Unterschied zwischen nicht versöhnen kann int error(char *fmt, ...)
und int error(char *fmt, va_list ap)
also für jede Funktion *printf
muss es zwei Versionen erstellen, dh eine Aufnahme ...
der andere nimmt auf va_list
, dies verdoppelt im Wesentlichen die Gesamtzahl der Funktionen. In Python können Sie verwenden *list()
oder **dict()
ein passieren va_list
wie ...
.
Hoffentlich kann zukünftiges C/C++ diese Art von Argumentverarbeitungsschema unterstützen.
Ich empfehle, Ihrer Frage die Tags “printf” und “variadic-functions” hinzuzufügen.
– Gabriel Staples
25. Juli 2018 um 19:10 Uhr