Lors de l'appel à une fonction, le compilateur génère une liste des arguments fournis qu'il empile dans la pile d'exécution rattachée au processus (pile de type LIFO).
Exemple
int puissance(int n, int x) { int p = 1; while(n--) p *= x; return p; } void main() { int m, k, r; k = 4; m = 2; r = puissance(k+3, m); }
A l'appel de la fonction puissance de l'exemple précédent il y a :
Ce type de passage d'arguments permet d'écrire des fonctions avec un nombre variable d'arguments.
Dans le prototype d'une telle fonction, on indiquera les arguments suivis de :
Exemple
void fonction(int a, ...); main() { int i = 10, j = 11, k = 12; printf("Avant appel fonction i = %d\n", i); printf("Avant appel fonction j = %d\n", j); printf("Avant appel fonction k = %d\n", k); fonction(i, j, k); } void fonction(int a, ...) { printf("Valeur de a = %d\n", a); printf("Recuperation de j = %d\n", *(&a + 1)); printf("Recuperation de k = %d\n", *(&a + 2)); }Cette technique de récupération d'arguments dans la pile, nécessite cependant que le programmeur connaisse les types des arguments en surnombre et qu'il ait un moyen d'arrêter la recherche.
Pour ce faire, le dernier argument fourni à l'appel de la fonction peut par exemple indiquer le nombre d'arguments en surnombre, ou bien ceux-ci peuvent être suivis par un argument supplémentaire de même type avec une valeur spéciale (valeur sentinelle).
Par contre la norme ne précise pas l'ordre dans lequel les arguments doivent être empilés, cette méthode de la pile n'est donc pas portable.
Pour assurer cette portabilité, chaque système propose des pseudo-constantes et pseudo-fonctions permettant au programmeur de gérer cette recherche.
Version ANSI
Les pseudo-constantes et pseudo-fonctions sont stockées dans le fichier en-tête stdarg.h :
Exemple
#include <stdio.h> #include <stdarg.h> main() { float moyenne(int nombre, ...); printf("moyenne = %f\n", moyenne(4, 1, 2, 3, 4)); printf("moyenne = %f\n", moyenne(5, 1, 2, 3, 4, 5)); } float moyenne(int nombre, ...) { int somme = 0, i; va_list arg; va_start(arg, nombre); for(i=0; i < nombre; i++) somme += va_arg(arg, int); va_end(arg); return somme/nombre; }