2009-09-03 11 views
2

Est-ce que quelqu'un sait comment je pourrais être en mesure d'implémenter l'arité variable pour les fonctions en C?Arité variable en C?

Par exemple, une fonction sommateur:

Somme (1,2,3,4 ...); (Prend un nombre variable d'arguments)

Merci!

+1

variable arité de quoi? Les fonctions? –

+0

S'il vous plaît être plus précis quant à ce que vous voulez. Un exemple de code (qui n'a pas besoin d'être compilé, de montrer simplement ce que vous essayez de réaliser, et comment vous le voudriez idéalement) serait extrêmement utile. –

+0

Parité, peut-être? Dans quel contexte? Dis nous en plus. – dmckee

Répondre

14

Une liste de paramètres variables d'ints. Ajuster le type si nécessaire:

#include <stdarg.h> 

void myfunc(int firstarg, ...) 
{ 
    va_list v; 
    int i = firstarg; 

    va_start(v, firstarg); 
    while(i != -1) 
    { 
     // do things 
     i = va_arg(v, int); 
    } 

    va_end(v); 
} 

Vous devez être en mesure de déterminer quand arrêter la lecture des variables. Ceci est fait avec un argument terminator (-1 dans mon exemple), ou en connaissant le nombre attendu d'arguments d'une autre source (par exemple, en examinant une chaîne de formatage comme dans printf).

6

Si tous les arguments supplémentaires sont du même type, vous pouvez également passer un tableau au lieu d'utiliser des macros variadiques.

Avec littéraux composés C99 et un peu de magie macro, cela peut sembler assez agréable:

#include <stdio.h> 

#define sum(...) \ 
    sum_(sizeof ((int []){ __VA_ARGS__ })/sizeof (int), (int []){ __VA_ARGS__ }) 

int sum_(size_t count, int values[]) 
{ 
    int s = 0; 
    while(count--) s += values[count]; 
    return s; 
} 

int main(void) 
{ 
    printf("%i", sum(1, 2, 3)); 
} 
+1

+1 C'est la meilleure approche, je l'utilise souvent. Mais cela échouera si vous fournissez une liste d'arguments vide. Pour contourner cela, utilisez la syntaxe suivante pour calculer le nombre d'arguments: "sizeof ((int []) {0, ## __ VA_ARGS __})/sizeof (int) -1". En cas de liste vide, ## __ VA_ARGS__ mange la virgule précédente. – qrdl

+0

pouvez-vous élaborer à ce sujet? semble abstrait à moi, merci :) – nubela

+0

@nubela: voir http://stackoverflow.com/questions/1385695/help-me-understand-this-short-chunk-of-code/1386555#1386555 – Christoph