fonctions a nombres de parametres variables

fonctions a nombres de parametres variables - C - Programmation

Marsh Posté le 15-10-2006 à 03:20:17    

Bonjour.
je souhaiterais en C faire une fonction ayant un nombre variable de parametres.
 
je déclare donc ma fonction ainsi :

Code :
  1. #include <stdarg.h>
  2. void generate_matrix(int width,...)
  3. {
  4. va_list varg;//Variable identifiant le prochain paramètre.  
  5. va_start(varg, width);
  6. int height=va_arg(varg, int);
  7. printf("height : %d\n", height);
  8. }


Cependant, j'aimerais bien savoir comment tester l'existence de ce parametre avant de m'en servir?
en effet, si je fais generate_matrix(5,3), j'aurais a l'ecran "3".
Mais si je fais generate_matrix(5), j'aurai a l'ecran n'importe quoi.
 
Comment puis-je alors savoir si mon argument existe avant d'assigner sa valeur à une variable?

Message cité 2 fois
Message édité par sky_99 le 15-10-2006 à 03:34:56
Reply

Marsh Posté le 15-10-2006 à 03:20:17   

Reply

Marsh Posté le 15-10-2006 à 04:43:18    

sky_99 a écrit :

Comment puis-je alors savoir si mon argument existe avant d'assigner sa valeur à une variable?


Tu ne peux pas. Il faut un autre mécanisme pour passer le nombre et le type des arguments. Typiquemet, une fonction à arguments variable sera de la forme va_func(T op, ...) ou l'argument "op" permet à vafunc de connaitre le nombre et le type des autres arguments.
 
Prend l'exemple de printf et de ioctl :

Code :
  1. int printf(const char *format, ...);
  2. int ioctl(int d, int request, ...);


 
Dans le cas de printf, c'est "format" qui permet de connaitre le nombre et le type des arguments. Su tu lui passe "blah blah %s blah blah %d", printf sait qu'il y deux arguments variables, le premier étant un char * et le deuxième étant un int. Dans le cas d'ioctl, c'est "request" qui remplit le même rôle. Typiquement dans l'implémentation de ioctl pour un device donné, tu auras un "switch (request)" dont chaque "case" connait le nombre et le type des arguments variables.

Reply

Marsh Posté le 15-10-2006 à 05:43:06    

ouarf... :/  
merci des infos!
 
Dans tous les cas, j'espere qu'en C++ y'aura pas tous ces problemes...
plus je fais du C, plus je trouve ce langage penible :|
 
Mais j'y pense... est il possible dans ce cas de faire en C une fonction ayant un nombre fixe d'arguments, mais un comportement par defaut quand certains ne sont pas remplis?
 
par ex:

Code :
  1. void func(int bidule, char machin)
  2. {
  3. //si machin n'est pas defini, alors machin=5
  4. //traitements avec bidule et machin=5
  5. }


Message édité par sky_99 le 15-10-2006 à 05:46:07
Reply

Marsh Posté le 15-10-2006 à 09:44:12    

pas en C, mais en C++ oui, ce sont les paramètres par défaut

Code :
  1. void func(int bidule, char machin = 5)
  2. {
  3.   //si machin n'est pas defini, alors machin=5
  4.   //traitements avec bidule et machin=5
  5. }


 
Pour le nombre variable de paramètres, sache déjà que le C est un des seuls langages à autoriser ça. Le Pascal ou le Java ne peuvent pas par exemple.
Par contre ça n'a pas été amélioré avec le C++, désolé.
 
Si tu fais un peu d'assembleur, tu sauras pourquoi une fonction ne peut pas directement connaitre le nombre d'arguments sur la pile.
Un technique simple pour t'aider : passe tous tes paramètres par pointeur et mets un NULL en dernier paramètre pour indiquer la fin des parametres.


Message édité par jesus_christ le 15-10-2006 à 09:44:19
Reply

Marsh Posté le 15-10-2006 à 10:54:03    

sky_99 a écrit :

je souhaiterais en C faire une fonction ayant un nombre variable de parametres.
 
Comment puis-je alors savoir si mon argument existe avant d'assigner sa valeur à une variable?


C'est exactement le rôle assigné au premier paramètre d'une fonction variadic. A toi de définir une manière d'indiquer le nombre et éventuellement le type des paramètres si il peut changer. L'exemple le plus connu est évidemment *printf().
 
La méthode choisie doit être documentée et être assimilée par celui qui utilise la fonction. Evidemment, le non respect de la méthode entraine un comportement indéterminé. Bienvenu dans le monde magique du langage C.
 
NOTA : les fonctions variadic sont , à l'évidence, sources de problèmes. Il faut tout faire pour éviter ça. Si le type est stable, un pointeur sur le premier élément d'un tableau et une taille suffisent dans tous les cas. Même pour des cas plus tordus, une structure avec union est encore préférable à l'infernal variadic.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 15-10-2006 à 10:55:58

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-10-2006 à 18:01:52    

en fait ce que j'aurais voulu faire, ça aurait été quelquechode du genre fonction(variable, mode), et si mode n'est pas defini, traiter avec un truc par defaut. Donc, grace à vos indications, j'apprends que ce n'est possible facilement qu'en C++ (bon point ici pour ce langage).
 
En revanche, en utilisant ce que dit jesus_christ, avec une liste de pointeurs, on peut toujours faire cela!
 
Reste a present le probleme de l'identification des variables (je n'aime pas ces histoires de va_list et autres). Mais on pourrait eventuellement le faire avec un pointeur sur un tableau de pointeurs...
Les arguments fixes ayant une place precise, et comme premier argument variable, on aurait un deuxieme tableau de pointeurs indiquant le "nom" des variables, et a la suite du premier tableau, leur valeur...
 
M'enfin, ce serait bien sur dans le cas ou ce serait vraiement necessaire...
 
(en fait pourquoi pas carrement une liste chainée... ça serait plus simple!)
 
 
(en fait je pense que ce qui me gene le plus en C, en dehors de l'absence de petites fonctions comme is_set(var) ou exists(var), c'est l'absence d'une doc "officielle" et unifiée, comme la doc php sur php.net... (ou java par ex, meme si je prefere celle de php)
 
En tous cas, merci des infos, ça me donnerait *presque* envie de coder en C pour le plaisir  :whistle:

Message cité 1 fois
Message édité par sky_99 le 15-10-2006 à 18:05:45
Reply

Marsh Posté le 15-10-2006 à 18:18:09    

sky_99 a écrit :

(en fait je pense que ce qui me gene le plus en C, en dehors de l'absence de petites fonctions comme is_set(var) ou exists(var), c'est l'absence d'une doc "officielle" et unifiée, comme la doc php sur php.net... (ou java par ex, meme si je prefere celle de php)


http://www.open-std.org/jtc1/sc22/ [...] /n1124.pdf
 
Have fun !


Message édité par Emmanuel Delahaye le 15-10-2006 à 18:18:36

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 16-10-2006 à 04:32:00    

Emmanuel Delahaye a écrit :

Si le type est stable, un pointeur sur le premier élément d'un tableau et une taille suffisent dans tous les cas.


Mieux: Une structure contenant
- le tableau d'éléments
- sa taille allouée
Eventuelement d'autres trucs comme
- le nombre d'éléments réellement contenus (peut être infèrieur à la taille allouée)
- un pointeur de traitement
 
Puis tu passes à ta fonction l'adresse de cette structure. Cela se rapproche fortement de la philosophie "objet"...

Message cité 1 fois
Message édité par Sve@r le 16-10-2006 à 04:32:38

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 16-10-2006 à 11:07:08    

Sve@r a écrit :

Mieux: Une structure contenant
- le tableau d'éléments
- sa taille allouée
Eventuelement d'autres trucs comme
- le nombre d'éléments réellement contenus (peut être infèrieur à la taille allouée)
- un pointeur de traitement
 
Puis tu passes à ta fonction l'adresse de cette structure. Cela se rapproche fortement de la philosophie "objet"...


http://mapage.noos.fr/emdel/clib.htm
Modules FARR et FSTR


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed