0Pricing
C Academy · Leçon

Macros stdarg

va_list, va_start, va_arg

Macros stdarg est une leçon C Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C Academy comprend 4 leçons au total.

Que sont les fonctions à nombre variable d'arguments ?

Une fonction à nombre variable d'arguments accepte un nombre variable d'arguments. Vous en avez déjà utilisé une : printf peut recevoir autant de valeurs que nécessaire.

Le langage C vous permet d'en écrire avec les macros de <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;
}

Les points de suspension

Vous déclarez une fonction à nombre variable d'arguments en plaçant ... (les points de suspension) comme dernier paramètre.

Au moins un paramètre nommé doit le précéder, afin que la fonction sache où commence la partie variable.

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

Inclure stdarg.h

Pour lire les arguments variables, vous avez besoin de #include <stdarg.h>.

Cette directive définit le type va_list ainsi que les macros va_start, va_arg et 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 et va_start

Déclarez une variable va_list pour suivre la position actuelle. Appelez ensuite va_start(list, last) en lui transmettant le dernier paramètre nommé.

La liste pointe alors vers le premier argument variable.

#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 : lire des valeurs

va_arg(list, type) renvoie l'argument suivant et avance dans la liste. Vous devez lui indiquer le type exact à lire.

Chaque appel avance d'un 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 : nettoyage

Appelez toujours va_end(list) lorsque vous avez fini la lecture. Cette macro effectue tout le nettoyage nécessaire à la plateforme.

Son oubli entraîne un comportement indéfini sur certains systèmes.

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

Savoir combien d’arguments

Les macros ne peuvent pas vous indiquer combien d’arguments ont été transmis. Vous devez le préciser vous-même.

Une approche courante consiste à utiliser un paramètre de comptage initial, comme dans 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;
}

Utiliser une valeur sentinelle

Une autre façon de marquer la fin consiste à utiliser une sentinelle : une valeur spéciale de terminaison que l’appelant doit inclure, comme -1 ou NULL.

Itérez jusqu’à la lecture de la sentinelle.

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

Promotions par défaut des arguments

Les arguments variadiques subissent des promotions par défaut : char et short deviennent int, et float devient double.

Lisez donc toujours les petits entiers comme des int et les nombres flottants comme des double avec 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;
}

Copier une va_list

Si vous devez parcourir les arguments deux fois, utilisez va_copy(dest, src) pour dupliquer la liste avant de la lire.

Vous ne pouvez pas réutiliser une va_list après va_end sans la redémarrer avec 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;
}

Calculer une moyenne

En combinant le schéma de comptage avec la lecture de nombres flottants, nous pouvons calculer la moyenne d’une liste de nombres transmis de manière variadique.

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

Vérification rapide

Vérifiez votre compréhension des macros de stdarg.

Récapitulatif

Vous avez appris le mécanisme variadique :

  • Déclarez-le avec ... après au moins un paramètre nommé.
  • va_start(list, last) commence la lecture, va_arg(list, type) lit un argument et va_end(list) effectue le nettoyage.
  • Les macros ne connaissent pas le nombre d’arguments : utilisez un paramètre de comptage ou une sentinelle.
  • Tenez compte des promotions par défaut : lisez les petits entiers comme des int et les nombres flottants comme des double.

Questions Fréquemment Posées

La leçon « Macros stdarg » est-elle gratuite ?

Oui — le texte complet de « Macros stdarg » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C Academy, passe à CoddyKit PRO. Le cours C Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Macros stdarg » ?

va_list, va_start, va_arg Tu pratiques C Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C Academy ?

Aucune expérience préalable n'est requise. C Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Macros stdarg » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C Academy ?

Oui. Chaque leçon C Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Macros stdarg
  2. Écrire des fonctions semblables à printf
  3. Problèmes de sûreté des types
  4. Exemples pratiques
← Retour à C Academy