|
Trouver une ressource
Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !
FONCTIONS À TAILLE VARIABLE D'ARGUMENTS
Information sur la source
Description
Voici un programme en C,sauf pour les commentaires: '//' au lieu de '/* ... */' car le C est assez embetant sur ce point, le C++ est pour ceci mieux. Passons le fait que ce programme soit plus en C que en C++ ... Voici le but de ce programme : savoir utiliser des fonctions à taille variable d'arguments, ceci est très rare mais parfois très utile ... les fonctions <printf>,<fprintf>,<sprintf>,<vsprintf>, ... sont des fonctions à taille variable d'arguments. Attention : l'utilisation de fonctions à taille variable d'arguments est dangereux car si la syntaxe est incorrecte,he bien le programmme continue. Après tout ce blabla voici enfin comment illustrer le problème : nous allons programmé une fontion <myPrint> qui prend des arguments qui vont par couple, i.e. le premier argument est le type du second. <myPrint> affichera ce second argument. <myPrint> return TRUE,si le type de l'argument est correct,sinon FALSE. Vous pourrez remarquer que la fonction <cout> en C++, fait le meme boulot, meme en plus amélioré,mais je fais du C et non du C++ ...
Source
- // pour les <printf> ...
- #include <stdio.h>
- // pour les <va_arg> ...
- #include <stdarg.h>
-
- // voici quelques utilitaires:
- // meme si ce n'est pas neccessaire,certains compilateurs (notamment les anciens)
- // ne connaissent pas le type <BOOL>
- typedef int BOOL;
- #define TRUE (1)
- #define FALSE (0)
-
- // voici tout les types que peut gérer la fonction <myPrint> :
- // le type TYPE_CHAR n'affiche que le caractère et non sa valeur
- //---------------------------------
- #define TYPE_INT 1
- //---------------------------------
- #define TYPE_LONG 2
- //---------------------------------
- #define TYPE_DOUBLE 3
- //---------------------------------
- #define TYPE_CHAR 4
- #define TYPE_STRING 5
- //---------------------------------
-
-
- // Voici comment prototyper la fonction <myPrint> :
-
- // Attention il faut que la fonction est au moins un argument fixe
- // sinon je ne sais pas faire
- // (je ne suis pas sur que l'on puisse le faire,mais bon...)
- // et puis je ne pense pas que cela arrive un jour.
- // Donc le premier argument est le premier nombre de type, ce qui est
- // équivalent au nombre de 'chose' que vous voulez afficher
- // car à chaque 'chose' on associe un type
-
- BOOL myPrint(int,...);
-
- // Voici LA fonction <myPrint> :
- BOOL myPrint(int nbChose,...)
- {
- // <listArg> est la list d'arguments variables du type <va_list>
- // défini dans <stdarg.h>
- va_list listArg;
-
- // on initialise <listArg> grace à <va_start>
- // on est obligé de passer en argument le nom du dernier argument fixe
- // cela peut paraitre absurde mais il faut savoir que <va_start> est une macro ...
- // donc ici le nom du dernier argument fixe est 'nbChose'
- va_start(listArg,nbChose);
-
- while(nbChose >= 1)
- {
- int type;
- // <va_arg> est une macro retourne l'argument variable courant
- // dont le type est le second argument de <va_arg>
- // ceci peut encore paraitre étonnant mais c'est une macro...
- type = va_arg(listArg,int);
-
- switch(type)
- {
- case TYPE_INT:
- {
- int a;
- a = va_arg(listArg,int);
- printf("%d",a);
- }
- break;
- case TYPE_LONG:
- {
- long a;
- a = va_arg(listArg,long);
- printf("%d",a);
- }
- break;
- case TYPE_DOUBLE:
- {
- double a;
- a = va_arg(listArg,double);
- printf("%f",a);
- }
- break;
- case TYPE_CHAR:
- {
- char a;
- a = va_arg(listArg,char);
- printf("%c",a);
- }
- break;
- case TYPE_STRING:
- {
- char *a;
- a = va_arg(listArg,char *);
- printf("%s",a);
- }
- break;
- default:
- {
- printf("Type inconnu ...\n");
- // meme si il y a un probleme on fait bien le travail
- va_end(listArg);
- return FALSE;
- }
- }
-
- // retourner à la ligne pour séparer les 'choses'
- printf("\n");
-
- // on a traité deux arguments, donc un 'nbChose'
- nbChose --;
- }
-
- // on fait bien le travail
- va_end(listArg);
-
- // ici tout va bien
- return TRUE;
- }
-
- int main(int argc,char **argv)
- {
-
- // ces deux lignes permettent les arguments <argc> et <argv>
- // soient non-utilisés et que le compilateur soit content, car
- // je ne sais pas quel est le niveau de 'warning' que vous avez :
- // le compilateur pourrait raler comme quoi
- // ces deux variables ne sont pas référencées ...
- (void) argc;
- (void) argv;
-
- // ici on utilise la fonction <myPrint> :
- myPrint(2,TYPE_STRING,"voici le nombre cent : (int)",TYPE_INT,100);
- myPrint(2,TYPE_STRING,"voici le nombre cent : (long)",TYPE_LONG ,100);
- myPrint(2,TYPE_STRING,"voici le centieme caractere :",TYPE_CHAR,100);
- myPrint(2,TYPE_STRING,"voici environ pi :",TYPE_DOUBLE,3.1415926435);
-
- // regarder ceci :
- // tout ce peut vous paraitre n'importe quoi.Certe.
- // Mais est-ce-que ça va marcher ?
- // OUI !!! car le nombre de 'chose' est 0
- // donc <myPrint> ne lira pas "tralala" ...
- myPrint(0,"tralala",TYPE_CHAR,"coucou",1.23456789,TYPE_LONG * TYPE_DOUBLE);
-
- // en revanche :
- // ceci est dangereux (c'est pourquoi je le met en comentaire)
- // ---> myPrint(0,"tralala",TYPE_CHAR);
- // car il n'y a rien après <TYPE_CHAR>
-
- getch();
-
- // retourner 0 car ici tout va bien
- return 0;
- }
// pour les <printf> ...
#include <stdio.h>
// pour les <va_arg> ...
#include <stdarg.h>
// voici quelques utilitaires:
// meme si ce n'est pas neccessaire,certains compilateurs (notamment les anciens)
// ne connaissent pas le type <BOOL>
typedef int BOOL;
#define TRUE (1)
#define FALSE (0)
// voici tout les types que peut gérer la fonction <myPrint> :
// le type TYPE_CHAR n'affiche que le caractère et non sa valeur
//---------------------------------
#define TYPE_INT 1
//---------------------------------
#define TYPE_LONG 2
//---------------------------------
#define TYPE_DOUBLE 3
//---------------------------------
#define TYPE_CHAR 4
#define TYPE_STRING 5
//---------------------------------
// Voici comment prototyper la fonction <myPrint> :
// Attention il faut que la fonction est au moins un argument fixe
// sinon je ne sais pas faire
// (je ne suis pas sur que l'on puisse le faire,mais bon...)
// et puis je ne pense pas que cela arrive un jour.
// Donc le premier argument est le premier nombre de type, ce qui est
// équivalent au nombre de 'chose' que vous voulez afficher
// car à chaque 'chose' on associe un type
BOOL myPrint(int,...);
// Voici LA fonction <myPrint> :
BOOL myPrint(int nbChose,...)
{
// <listArg> est la list d'arguments variables du type <va_list>
// défini dans <stdarg.h>
va_list listArg;
// on initialise <listArg> grace à <va_start>
// on est obligé de passer en argument le nom du dernier argument fixe
// cela peut paraitre absurde mais il faut savoir que <va_start> est une macro ...
// donc ici le nom du dernier argument fixe est 'nbChose'
va_start(listArg,nbChose);
while(nbChose >= 1)
{
int type;
// <va_arg> est une macro retourne l'argument variable courant
// dont le type est le second argument de <va_arg>
// ceci peut encore paraitre étonnant mais c'est une macro...
type = va_arg(listArg,int);
switch(type)
{
case TYPE_INT:
{
int a;
a = va_arg(listArg,int);
printf("%d",a);
}
break;
case TYPE_LONG:
{
long a;
a = va_arg(listArg,long);
printf("%d",a);
}
break;
case TYPE_DOUBLE:
{
double a;
a = va_arg(listArg,double);
printf("%f",a);
}
break;
case TYPE_CHAR:
{
char a;
a = va_arg(listArg,char);
printf("%c",a);
}
break;
case TYPE_STRING:
{
char *a;
a = va_arg(listArg,char *);
printf("%s",a);
}
break;
default:
{
printf("Type inconnu ...\n");
// meme si il y a un probleme on fait bien le travail
va_end(listArg);
return FALSE;
}
}
// retourner à la ligne pour séparer les 'choses'
printf("\n");
// on a traité deux arguments, donc un 'nbChose'
nbChose --;
}
// on fait bien le travail
va_end(listArg);
// ici tout va bien
return TRUE;
}
int main(int argc,char **argv)
{
// ces deux lignes permettent les arguments <argc> et <argv>
// soient non-utilisés et que le compilateur soit content, car
// je ne sais pas quel est le niveau de 'warning' que vous avez :
// le compilateur pourrait raler comme quoi
// ces deux variables ne sont pas référencées ...
(void) argc;
(void) argv;
// ici on utilise la fonction <myPrint> :
myPrint(2,TYPE_STRING,"voici le nombre cent : (int)",TYPE_INT,100);
myPrint(2,TYPE_STRING,"voici le nombre cent : (long)",TYPE_LONG ,100);
myPrint(2,TYPE_STRING,"voici le centieme caractere :",TYPE_CHAR,100);
myPrint(2,TYPE_STRING,"voici environ pi :",TYPE_DOUBLE,3.1415926435);
// regarder ceci :
// tout ce peut vous paraitre n'importe quoi.Certe.
// Mais est-ce-que ça va marcher ?
// OUI !!! car le nombre de 'chose' est 0
// donc <myPrint> ne lira pas "tralala" ...
myPrint(0,"tralala",TYPE_CHAR,"coucou",1.23456789,TYPE_LONG * TYPE_DOUBLE);
// en revanche :
// ceci est dangereux (c'est pourquoi je le met en comentaire)
// ---> myPrint(0,"tralala",TYPE_CHAR);
// car il n'y a rien après <TYPE_CHAR>
getch();
// retourner 0 car ici tout va bien
return 0;
}
Conclusion
ps: Chaque bug trouvé est la bienvenu
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
|