ça marche bien. Mais je cherche à faire un peu plus compliqué...
j'ai une première fonction:
int somme(int nbr, ...)
{
int i,s=0;
va_list(pt);
va_start(pt,nbr);
for(i=0 ; i < nbr ; i++) /* "<" = infèrieur, mais je n'arrive pas à le faire passer*/
s=s+va_arg(pt,int);
va_end(pt);
return s;
}
et je voudrai l'utiliser dans une fonction moyenne par exemple, mais je ne sais pas si on peu passer les arguments "..." à une autre fonction, par exemple pour faire un truc du style:
float moyenne(int nbr, ...)
{
return (somme(nbr,...)/nbr);
}
ou bien si il faut que je stocke les argument de moyenne dans un tableau et les restitus à la fonction somme?
je sais pas si je me suis fait comprendre, j'espère que oui :-)
merci d'avance.
# HUm
Posté par cho7 (site web personnel) . Évalué à 1.
Tu devrais effectivement stocker tous les 1ers paramètres recus dans un tableau, et faire suivre ce dernier à somme.
[^] # Re: HUm
Posté par jojolapine . Évalué à 0.
merci pour la réponse....
et pendant que j'y suis sur ces fonctions, première chose, le nombre de paramètre est-il infini (ou quasi, la limite étant la mémoire de l'ordi)
ou y a-t-il une limite plus petite?
et ensuite, ya t'il un moyen pour "revenir d'un cran" sur la variable précédente ou va_args efface t'il les variables après les avoir récupérée ?
[^] # Re: HUm
Posté par gaaaaaAab . Évalué à 2.
bon, ça c'est deux questions en fait.
Y'a-t-il un moyen de revenir d'un cran ?
La réponse est non. Sur une va_list, tu ne peux appeler que va_start, va_arg et va_end.
L'effet de toute autre utilisation d'une va_list est indéfini.
va_args efface-t'il les variables après les avoir récupérées ?
On va dire que je suis négatif, mais encore une fois, la réponse une non.
Tu as tout à fait le droit d'appeler plusieur fois va_start. Ca te repositionner à chaque fois sur le début de la liste. Par contre, je ne sais pas si tu peux imbriqué les appels (genre refaire un va_start entre un va_start et un va_end). Dans le doute, je ne m'y risquerais pas.
Tu peux aussi jeter un oeil à va_copy
[^] # Re: HUm
Posté par gaaaaaAab . Évalué à 2.
dans la FAQ cd comp.lang.c :
http://www.eskimo.com/~scs/C-faq/q15.12.html
[^] # Re: HUm
Posté par mathieu mathieu (site web personnel) . Évalué à 2.
bref, on placant l'adresse du premier parametre de la va_list en parametre de la fonction somme, il n'est pas impossible que cela fonctionne!
A+
Mathieu
[^] # Re: HUm
Posté par Christophe Fergeau . Évalué à 2.
# macro à nombre variable d'arguments
Posté par Bastien Mourgues . Évalué à 1.
#define MOYENNE(nbr, args...) (somme((nbr), args) / (nbr))
utilisation :
float f = MOYENNE(3, 1, 2, 3);
Après, faut aimer les macros :)
[^] # Re: macro à nombre variable d'arguments
Posté par jojolapine . Évalué à 0.
à quoi correspond la variable "args..."?
En gros on transmet les "..." à la fonction somme?
[^] # Re: macro à nombre variable d'arguments
Posté par Bastien Mourgues . Évalué à 1.
En fait, teste, et tu veras ! ;)
[^] # Re: macro à nombre variable d'arguments
Posté par jojolapine . Évalué à -1.
Je veu pouvoir réapliquer ce que j'ai appris dans d'autres exemples....
mais c'est gentil quand-même!
[^] # Re: macro à nombre variable d'arguments
Posté par Bastien Mourgues . Évalué à 2.
tu copies la ligne dans ton fichier, exemple :
macrotest.c :
#define MOYENNE(nbr, args...) (somme((nbr), args) / (nbr))
int
main(int argc, char *argv[])
{
float f = MOYENNE(3, 1, 2, 3);
}
Pour voir ce que ça fait : gcc -E macrotest.c (tu fais passer le préprocesseur pour étendre la macro), ce qui donne :
int
main(int argc, char *argv[])
{
float f = (somme((3), 1, 2, 3) / (3));
}
Change les paramètres de MOYENNE dans le main, recommence la procédure ci dessus, et vois ce que ça donne.
Finalement, après quelques tests, tu te rends compte que la liste de paramètres variables se note nom... dans le prototype de la macro, et qu'on l'appelle par nom dans le corps de la macro.
Si tu as toujours des doutes, le texte "macro à nombre variable d'arguments" envoyé à google ( http://www.google.fr/search?hl=fr&q=macro+%C3%A0+nombre+(...)
) te renvoie entre autres la page : http://fr.wikibooks.org/wiki/Programmation_C_Pr%C3%A9process(...)
et libre à toi d'en trouver d'autres si tu veux te documenter sur le sujet.
Tout ça pour dire : vouloir savoir, c'est bien, attendre que ça tombe tout cuit, ça l'est moins. Quand tu as quelques pistes, si tu ne fais pas l'effort de fouiller par toi même, tu ne vas pas aller bien loin :-<
bon courage quand même.
[^] # Re: macro à nombre variable d'arguments
Posté par jojolapine . Évalué à 0.
mais c'est juste que lorsque je regarde sur la page http://fr.wikibooks.org/wiki/Programmation_C_Pr%C3%A9process(...) , et bien il y a une macros comme:
#define debug(message, ...) fprintf( stderr, __FILE__ ":%d:" message "\n", __LINE__, __VA_ARGS__ ),
et içi il n'ya pas de 'nom...' comme tu le dis, c'est pour ça que je ne comprend pas trop comment ça marche, comprend que se soit un peu déroutant....
encore dsl
# il suffit de faire une fonction qui accepte une va_list
Posté par panda panda . Évalué à 1.
c'est utilise tres frequement, notamment pour appeller vfprintf.
si je veux faire une fonction qui log au moyen d'une structure log je peux par exemple ecrire
struct loginfo {
const char *channel;
FILE *fd;
};
void
log_log(struct loginfo *li, const char *fmt, ...)
{
va_list ap;
fprintf(li->fd, "%s: ", channel);
va_start(ap, fmt);
vfprintf(li->fd, fmt, ap);
va_end(ap);
fprintf(li->fd, "\n");
}
int
main(int ac, char **av)
{
struct loginfo li;
memset(&li, 0, sizeof (struct loginfo));
li.fd = stdout;
li.channel = 'monprog';
log_log(&li, "ca marche tout comme printf, %s", "c'est vraiment trop bien");
return 0;
}
en resume y aura pas trop de soucis pour transposer de ton cote:
int
moyenne(int nbr, ...)
{
int sum;
va_list ap;
va_start(ap,nbr);
sum = somme(nbr, ap);
va_end(ap);
return sum / nbr;
}
int
somme(int nbr, va_list args)
{
int sum;
for (sum = 0; nbr--;)
sum += va_arg(args, int);
return sum;
}
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.