fonctions C avec nombre infini d'argument - C++ - Programmation
Marsh Posté le 23-11-2002 à 18:59:37
pourquoi tu passes pas simplement un pointeur sur le tableau ?
Marsh Posté le 23-11-2002 à 19:01:52
Et une fonction à nombre variable d'arguments ?
cf stdarg.h (va_arg, va_start, va_end)
Marsh Posté le 23-11-2002 à 19:02:02
yep pour cet exemple oui, mais mon objectif est de réussir à mettre en place ce système d'arguments infinis pour l'utiliser dans certains cas où c'est la seule possibilité.
Dans cet exemple il est vrai que ça n'a pas d'intérêt, mais c'est un exemple pour expliciter ce que je cherche à faire...
Marsh Posté le 23-11-2002 à 19:03:49
antp a écrit a écrit : Et une fonction à nombre variable d'arguments ? cf stdarg.h (va_arg, va_start, va_end) |
yep j'utilise ces macros pour définir ma fonction en elle-même mais cela ne résoud pas mon problème d'appel à la fonction.
Le but est que la machine fasse le lien X nombres = > X arguments dans l'appel à la fonction.
Marsh Posté le 23-11-2002 à 19:35:56
Je pense que je sais le faire en Pascal mais en C je vois pas trop comment le faire
Marsh Posté le 23-11-2002 à 19:49:03
dans ce cas tu peux toujours m'expliciter une fonction Pascal qui le fait Je devrais pouvoir l'importer dans mes programmes C si je n'arrive pas à en faire un équivalent en C )
Marsh Posté le 23-11-2002 à 19:50:40
Bhen en Pascal tu peux passer plus facilement des "array", vu qu'un tableau peut avoir une taille variable.
Tu passes un "const array" à la fonction, puis avec les fonctions Low & High tu parcours le tableau.
Un peu comme ce que fait la fonction Format.
Note qu'en C tu pourrais aussi faire un tableau, mais tu ne peux pas mélanger différents types dans un tableau il me semble...
Marsh Posté le 23-11-2002 à 20:05:59
le plus simple est de passer ton tableau entier en argument et le nb de valeur que tu voudras sommer:
sommer(float *nombres, int nbval);
passer les valeurs d'un tableau une à une ds une fonction enleve tout le benefice des tableaux
Marsh Posté le 23-11-2002 à 20:26:13
oui mais je le répéte, ici le tableau n'est qu'un exemple, je souhaite utiliser ce système pour travailler avec d'autres objets. Il est vrai que dans cet exemple il est inutile de procéder comme cela, mais bon je cherche une solution globale
Marsh Posté le 24-11-2002 à 02:20:23
Pourquoi pas ça tout simplement
Code :
|
Par contre il faut convertir les "argv" (qui vont être des char*) que tu vas recevoir en int...
Mais normalement ca doit marcher
a+
Marsh Posté le 24-11-2002 à 02:51:47
Ça n'est pas permis par le C.
Le nombre d'arguments effectif doit être connu à la compilation.
Donc, tableau préalable, transmettre un pointeur.
Variante C99 pour construire le tableau sur place:
Code :
|
Marsh Posté le 24-11-2002 à 02:58:44
Musaran a écrit a écrit : Ça n'est pas permis par le C. Le nombre d'arguments effectif doit être connu à la compilation. Donc, tableau préalable, transmettre un pointeur. Variante C99 pour construire le tableau sur place:
|
tu es sur je ne mais pas t'as parole en doute mais je viens de tester le prog chez moi et ca n'a posé aucun problème même pas de warning.
Alors si t'as une réponse à ça je suis preneur
a+
Marsh Posté le 24-11-2002 à 11:31:31
marloS a écrit a écrit : oui mais je le répéte, ici le tableau n'est qu'un exemple, je souhaite utiliser ce système pour travailler avec d'autres objets. Il est vrai que dans cet exemple il est inutile de procéder comme cela, mais bon je cherche une solution globale |
justement tu as un exemple ou un pointeur et un compteur sur le nombre d'arguments (voire les deux dans une structure)
ne marcheraient pas?
tu peux meme les mettre sur une pile faite a la main.
ou dans une structure plus complexe comme un arbre si tu as plusieurs types d'operations.
LeGreg
Marsh Posté le 24-11-2002 à 12:11:36
Musaran a écrit a écrit : Variante C99 pour construire le tableau sur place: |
ha enfin, ça manquait fort au C ce genre de truc je trouve
Mais on peut pas mélanger plusieurs types de variable je suppose ?
Marsh Posté le 24-11-2002 à 21:58:00
Musaran a écrit a écrit : Ça n'est pas permis par le C. Le nombre d'arguments effectif doit être connu à la compilation. |
et printf?
Marsh Posté le 25-11-2002 à 02:37:28
-keiji- a écrit a écrit : tu es sur je ne mais pas t'as parole en doute mais je viens de tester le prog chez moi et ca n'a posé aucun problème même pas de warning. |
Mais quel "prog" ? Tu ne donnes que des extraits...
La fonction C99 dont je parle existait déjà sous gcc.
antp a écrit a écrit : Mais on peut pas mélanger plusieurs types de variable je suppose ? |
Tu veux dire faire un agrégat-structure ?
Code :
|
Je sais plus, et j'ai pas C99 sous la main pour tester.
Ace17 a écrit a écrit : et printf? |
Je-voulais-dire:
Le nombre d'arguments effectif à l'appel de fonction doit être connu à la compilation.
Le C n'a aucun mécanisme "variable" à ce niveau, même si certaines implémentation sont capables d'allouer des tailles variables sur la pile (alloca).
Marsh Posté le 25-11-2002 à 09:32:51
Musaran a écrit a écrit : Tu veux dire faire un agrégat-structure ?
Je sais plus, et j'ai pas C99 sous la main pour tester. |
non, passer des types différents, comme en Pascal :
Format('%s = %d min %f sec', [label, minutes, secondes]);
On passe comme second paramètre un tableau construit "sur le tas" contenant une string, un Integer et un Double
Marsh Posté le 25-11-2002 à 19:33:41
antp a écrit a écrit : non, passer des types différents, comme en Pascal : Format('%s = %d min %f sec', [label, minutes, secondes]); On passe comme second paramètre un tableau construit "sur le tas" contenant une string, un Integer et un Double |
de toute facon c'est ce qui se passe en pratique
ce prototype a longueur variable c'est juste
une facon de passer un tableau dynamique sur la pile rien
de plus.
Et c'est faisable avec C grace aux conventions d'appel du C
mais ca ne doit pas etre beaucoup plus efficace que ce que fait Pascal.
LeGreg
Marsh Posté le 25-11-2002 à 19:38:08
bah y a pas de risque de dépassement vu qu'on connaît la taille du tableau, ce qui n'est pas le cas de va_arg il me semble, non ?
Marsh Posté le 26-11-2002 à 00:54:29
Exemple plus concret de cette fonction :
Code :
|
Donc en gros la macro va_start est utilisée pour affecter un pointeur, argument_ptr, vers le premier arg sur la pile. La macro va_arg renvoie une valeur du type défini et incrémente argumentp_tr vers l'argument suivant sur la pile. Lorsque argument_ptr rencontre la valeur finale 0, la macro va_end est utilisée pour affetcer une valeur à argument_ptr prohibant toute utilisation ultérieure du pointeur, jusqu'à ce que va_start le réinitialise...
Marsh Posté le 26-11-2002 à 04:30:59
antp a écrit a écrit : bah y a pas de risque de dépassement vu qu'on connaît la taille du tableau, ce qui n'est pas le cas de va_arg il me semble, non ? |
En C il faut toujours quelque chose en plus pour indiquer la taille.
-soit un argument supplémentaire (memset).
-soit un argument format duquel est déduit le nombre et/ou type (printf).
-soit une valeur spéciale terminale ('\0' des chaînes).
Marsh Posté le 23-11-2002 à 18:43:10
Salut à tous !
j'ai un petit soucis concernant la création de fonctions pouvant manipuler un nombre infini d'argument.
Pour expliquer mon problème je vais prendre un exemple simple :
supposons que je veuille écrire une fonction pour sommer X nombres saisis au clavier (la saisie de 0 entrainera la fin de la demande de saisie). J'écris donc simplement une fonction pouvant accepter un nombre infini d'arguments, et qui délimite la fin des arguments par 0 (dernier nombre saisi au clavier en toute logique). Rien de bien difficile donc.
Mon problème se pose au niveau de l'appel de la fonction : supposons que j'ai stocké les valeurs saisie dans un tableau de N flottants, je possède aussi la taille logique du tableau, il est donc très simple de le parcourir pour retrouver tous mes nombres saisis. Mais qu'en est-il à l'appel de la fonction pour sommer ? il est de la forme sommer(arg1, arg2, etc...) mais je n'arrive pas à généraliser cette écriture pour X arguments.
Voici une alternative peu efficace pour expliciter le problème.
Supposons que la taille logique de mon tableau de nombres saisis soit tl.
switch (tl)
{
case 0 : // rien de saisi
case 1 : return ; // 1 seul nombre de saisi, somme inutile
case 2 : return sommer(nombres[0], nombres[1]);
case 3 : return sommer(nombres[0], nombres[1], nombres[2]);
etc ....
}
Cette solution marche mais n'effectue aucune généralisation !
Comment remédier à celà, faire en sorte que si nb de nombres saisi = n (n > 1), alors appeler sommer avec n arguments ?
Merci
Message édité par marloS le 23-11-2002 à 18:48:35