0Pricing
C Academy · Lektion

Die stdarg-Makros

va_list, va_start, va_arg

Die stdarg-Makros ist eine kostenlose C Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C Academy-Kurs umfasst insgesamt 4 Lektionen.

Was sind Funktionen mit variabler Argumentanzahl?

Eine Funktion mit variabler Argumentanzahl akzeptiert eine variable Anzahl von Argumenten. Sie haben bereits eine verwendet: printf kann beliebig viele Werte annehmen.

In C können Sie mithilfe der Makros aus <stdarg.h> eigene solche Funktionen schreiben.

#include <stdio.h>

int main(void) {
    printf("%d %d %d\n", 1, 2, 3);
    printf("%s\n", "any count of args");
    return 0;
}

Die Ellipse

Sie deklarieren eine Funktion mit variabler Argumentanzahl, indem Sie ... (die Ellipse) als letzten Parameter verwenden.

Davor muss mindestens ein benannter Parameter stehen, damit die Funktion weiß, wo der variable Teil beginnt.

#include <stdio.h>
#include <stdarg.h>

void demo(int count, ...) {
    printf("This function takes %d extra args\n", count);
}

int main(void) {
    demo(3, 10, 20, 30);
    return 0;
}

stdarg.h einbinden

Um die variablen Argumente zu lesen, benötigen Sie #include <stdarg.h>.

Die Datei definiert den Typ va_list sowie die Makros va_start, va_arg und va_end.

#include <stdio.h>
#include <stdarg.h>

void show(int n, ...) {
    va_list args;
    va_start(args, n);
    va_end(args);
    printf("set up and cleaned up\n");
}

int main(void) {
    show(2, 5, 6);
    return 0;
}

va_list und va_start

Deklarieren Sie eine Variable vom Typ va_list, um die aktuelle Position zu verfolgen. Rufen Sie anschließend va_start(list, last) auf und übergeben Sie den letzten benannten Parameter.

Dadurch zeigt die Liste auf das erste variable Argument.

#include <stdio.h>
#include <stdarg.h>

void first(int count, ...) {
    va_list args;
    va_start(args, count);
    int value = va_arg(args, int);
    printf("first variadic arg = %d\n", value);
    va_end(args);
}

int main(void) {
    first(1, 99);
    return 0;
}

va_arg: Werte lesen

va_arg(list, type) gibt das nächste Argument zurück und rückt die Liste weiter. Sie müssen den exakten Typ angeben, der gelesen werden soll.

Jeder Aufruf bewegt die Position um ein Argument weiter.

#include <stdio.h>
#include <stdarg.h>

void three(int n, ...) {
    va_list args;
    va_start(args, n);
    int a = va_arg(args, int);
    int b = va_arg(args, int);
    int c = va_arg(args, int);
    printf("%d %d %d\n", a, b, c);
    va_end(args);
}

int main(void) {
    three(3, 7, 8, 9);
    return 0;
}

va_end: Aufräumen

Rufen Sie immer va_end(list) auf, wenn Sie das Lesen beendet haben. Dadurch wird jede vom System benötigte Bereinigung durchgeführt.

Wenn Sie dies vergessen, führt das auf manchen Systemen zu undefiniertem Verhalten.

#include <stdio.h>
#include <stdarg.h>

int add_two(int dummy, ...) {
    va_list args;
    va_start(args, dummy);
    int sum = va_arg(args, int) + va_arg(args, int);
    va_end(args);
    return sum;
}

int main(void) {
    printf("%d\n", add_two(0, 4, 6));
    return 0;
}

Anzahl der Argumente kennen

Die Makros können nicht feststellen, wie viele Argumente übergeben wurden. Sie müssen diese Information selbst bereitstellen.

Ein gängiger Ansatz ist ein führender Zählparameter, wie bei sum(3, a, b, c).

#include <stdio.h>
#include <stdarg.h>

int sum(int count, ...) {
    va_list args;
    va_start(args, count);
    int total = 0;
    for (int i = 0; i < count; i++)
        total += va_arg(args, int);
    va_end(args);
    return total;
}

int main(void) {
    printf("%d\n", sum(4, 1, 2, 3, 4));
    return 0;
}

Einen Sentinel-Wert verwenden

Eine andere Möglichkeit, das Ende zu kennzeichnen, ist ein Sentinel: ein spezieller Abschlusswert, den der Aufrufer übergeben muss, etwa -1 oder NULL.

Lesen Sie so lange, bis Sie den Sentinel erreichen.

#include <stdio.h>
#include <stdarg.h>

int sum_until_neg(int first, ...) {
    va_list args;
    va_start(args, first);
    int total = first, v;
    while ((v = va_arg(args, int)) != -1)
        total += v;
    va_end(args);
    return total;
}

int main(void) {
    printf("%d\n", sum_until_neg(10, 20, 30, -1));
    return 0;
}

Standardmäßige Argument-Promotions

Variadische Argumente unterliegen standardmäßigen Promotions: char und short werden zu int, und float wird zu double.

Lesen Sie kleine Ganzzahlen mit va_arg daher immer als int und Gleitkommazahlen als double.

#include <stdio.h>
#include <stdarg.h>

void show_double(int n, ...) {
    va_list args;
    va_start(args, n);
    double d = va_arg(args, double);
    printf("%.2f\n", d);
    va_end(args);
}

int main(void) {
    show_double(1, 3.5f);
    return 0;
}

Eine va_list kopieren

Wenn Sie die Argumente zweimal durchlaufen müssen, verwenden Sie vor dem Lesen va_copy(dest, src), um die Liste zu duplizieren.

Nach va_end können Sie eine va_list nicht wiederverwenden, ohne sie zuvor mit va_start neu zu initialisieren.

#include <stdio.h>
#include <stdarg.h>

void twice(int n, ...) {
    va_list a, b;
    va_start(a, n);
    va_copy(b, a);
    printf("%d %d\n", va_arg(a, int), va_arg(b, int));
    va_end(a);
    va_end(b);
}

int main(void) {
    twice(1, 42);
    return 0;
}

Einen Durchschnitt berechnen

Durch die Kombination des Zählmusters mit dem Lesen von Gleitkommazahlen können wir den Durchschnitt einer variadisch übergebenen Zahlenliste berechnen.

#include <stdio.h>
#include <stdarg.h>

double average(int count, ...) {
    va_list args;
    va_start(args, count);
    double sum = 0;
    for (int i = 0; i < count; i++)
        sum += va_arg(args, double);
    va_end(args);
    return sum / count;
}

int main(void) {
    printf("%.2f\n", average(3, 2.0, 4.0, 6.0));
    return 0;
}

Kurzer Test

Testen Sie Ihr Verständnis der stdarg-Makros.

Zusammenfassung

Sie haben den variadischen Mechanismus kennengelernt:

  • Deklarieren Sie ihn mit ... nach mindestens einem benannten Parameter.
  • va_start(list, last) beginnt, va_arg(list, type) liest, und va_end(list) räumt auf.
  • Die Makros kennen die Anzahl nicht — verwenden Sie einen Zählparameter oder einen Sentinel.
  • Beachten Sie die Standard-Promotions: Lesen Sie kleine Ganzzahlen als int und Gleitkommazahlen als double.

Häufig gestellte Fragen

Ist die Lektion „Die stdarg-Makros“ kostenlos?

Ja — der vollständige Text von „Die stdarg-Makros“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Die stdarg-Makros“?

va_list, va_start, va_arg Du übst C Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um C Academy zu starten?

Keine Vorkenntnisse erforderlich. C Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.

Wie lange dauert die Lektion „Die stdarg-Makros“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser C Academy-Lektion Code schreiben und ausführen?

Ja. Jede C Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Die stdarg-Makros
  2. Printf-ähnliche Funktionen schreiben
  3. Fragen der Typsicherheit
  4. Praktische Beispiele
← Zurück zu C Academy