C Academy · Lektion

Makrona i stdarg

va_list, va_start, va_arg.

Lektion 1 av 413 steg

Makrona i stdarg är en gratis lektion i C Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för C Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i C Academy innehåller totalt 4 lektioner.

Vad är variadiska funktioner?

En variadisk funktion accepterar ett varierande antal argument. Du har redan använt en sådan: printf kan ta emot hur många värden som helst.

I C kan du skriva egna variadiska funktioner med makrona i <stdarg.h>.

#include <stdio.h>

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

Ellipsen

Du deklarerar en variadisk funktion med ... (ellipsen) som den sista parametern.

Minst en namngiven parameter måste stå före den, så att funktionen vet var den variabla delen börjar.

#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;
}

Inkludera stdarg.h

För att läsa de variabla argumenten behöver du #include <stdarg.h>.

Det definierar typen va_list och makrona va_start, va_arg och 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 och va_start

Deklarera en variabel av typen va_list för att hålla reda på den aktuella positionen. Anropa sedan va_start(list, last) och skicka med den sista namngivna parametern.

Detta ställer listan på det första variabla argumentet.

#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: läsa värden

va_arg(list, type) returnerar nästa argument och flyttar listan framåt. Du måste ange den exakta typen som ska läsas.

Varje anrop går vidare med ett argument.

#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: städning

Anropa alltid va_end(list) när Ni har läst klart. Den utför den städning som plattformen behöver.

Om Ni glömmer detta leder det till odefinierat beteende på vissa system.

#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;
}

Ta reda på hur många argument

Makrona kan inte tala om för Er hur många argument som skickades med. Det måste Ni ange själv.

Ett vanligt sätt är att ha en inledande räknarparameter, som i 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;
}

Använda ett sentinelvärde

Ett annat sätt att markera slutet är en sentinel: ett särskilt avslutande värde som anroparen måste inkludera, till exempel -1 eller NULL.

Iterera tills Ni läser sentinelvärdet.

#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;
}

Standardkonverteringar av argument

Variadiska argument genomgår standardkonverteringar: char och short blir int, och float blir double.

Läs därför alltid små heltal som int och flyttal som double med va_arg.

#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;
}

Kopiera en va_list

Om Ni behöver gå igenom argumenten två gånger använder Ni va_copy(dest, src) för att duplicera listan innan Ni läser den.

Ni kan inte återanvända en va_list efter va_end utan att starta om via va_start.

#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;
}

Beräkna ett medelvärde

Genom att kombinera räknarmönstret med läsning av flyttal kan vi beräkna medelvärdet av en lista med variadiskt överförda tal.

#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;
}

Snabbtest

Testa Er förståelse av stdarg-makrona.

Sammanfattning

Ni har lärt Er den variadiska mekanismen:

  • Deklarera med ... efter minst en namngiven parameter.
  • va_start(list, last) startar, va_arg(list, type) läser och va_end(list) städar upp.
  • Makrona känner inte till antalet – använd en räknarparameter eller en sentinel.
  • Var uppmärksam på standardkonverteringar: läs små heltal som int och flyttal som double.
Gratis att börja

Lär dig C med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
39
Lektioner
144

Vanliga frågor

Är lektionen ”Makrona i stdarg” gratis?

Ja – hela texten till ”Makrona i stdarg” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i C Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i C Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Makrona i stdarg”?

va_list, va_start, va_arg. Ni övar på C Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig C Academy?

Du behöver inga förkunskaper. Utbildningen i C Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Makrona i stdarg”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här C Academy-lektionen?

Ja. Varje C Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Makrona i stdarg
  2. Skriv printf-liknande funktioner
  3. Problem med typsäkerhet
  4. Praktiska exempel
← Tillbaka till C Academy