[C] : préprocesseur et macro

: préprocesseur et macro [C] - Programmation

Marsh Posté le 22-04-2001 à 00:14:45    

Je me suis remis recemment au C et râââ putain j'avais oublié combien c'est POWERFULL !!!
Fiou ... 6 mois de VB ca ramolit :)
Alors voila ma question : comment on créé des macros ???
il me semble que c'est possible de faire un truc du genre
 
#macro &(CH1,CH2) strcat(CH1,CH2)
bon là c'est n'importe quoi :D
 
le but c'est de pouvoir écrire:
       chaine1 = chaine2 & chaine3
et le préprocesseur me génère :
       strcpy(chaine1,chaine2)
       strcat(chaine1,chaine3)
 
au fait, le tout en C et pas en C++ (pas de redefinition d'operateur ...)
 
et tant qu'on y est, comment ca marche le parametre "..." qui permet de passer un nombre infini de parametres (comme dans printf(char *,[arglist])) ???


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-04-2001 à 00:14:45   

Reply

Marsh Posté le 22-04-2001 à 10:57:24    

HelloWorld a écrit a écrit :

Je me suis remis recemment au C et râââ putain j'avais oublié combien c'est POWERFULL !!!
Fiou ... 6 mois de VB ca ramolit :)
Alors voila ma question : comment on créé des macros ???
il me semble que c'est possible de faire un truc du genre
 
#macro &(CH1,CH2) strcat(CH1,CH2)
bon là c'est n'importe quoi :D
 
le but c'est de pouvoir écrire:
       chaine1 = chaine2 & chaine3
et le préprocesseur me génère :
       strcpy(chaine1,chaine2)
       strcat(chaine1,chaine3)
 
au fait, le tout en C et pas en C++ (pas de redefinition d'operateur ...)
 
et tant qu'on y est, comment ca marche le parametre "..." qui permet de passer un nombre infini de parametres (comme dans printf(char *,[arglist])) ???




 
 
Salut !
 
Pour faire des macros en C, il suffit de faire :
 
#define nom_macro(param1,....,paramN) instruction
 
et printf s'utilise comme ça :
 
printf("texte" );
ou
printf("%d",entier);
ou
printf("%s",chaine_caracteres);
ou
printf("%c",caractere);
ou
printf("%d %s %c %f",entier,chaine_caracteres,caractere,decimal);
 
 
Si tu es sous Linux : fais un "man printf"
 
@+

 

[edit]--Message édité par HumanFactor--[/edit]

Reply

Marsh Posté le 22-04-2001 à 11:16:15    

Salut ! Pour gérer une liste variables de paramètres dans une fonction, il faut les lire avec les macros va_start, va_arg et va_end. Dans cet exemple, tous les arguments sont des entiers. Il faut qu'il y ait au moins un argument fixe dans le prototype de la fonction, et que la liste soit terminée par un marqueur (NULL ou 0 par exemple).
 
void fonction(char* texte, ...)
{
   va_list liste;
   int nombre;
 
   va_start(liste,texte); // Place le pointeur après le paramètre fixe "texte"
   
   while( (nombre=va_arg(liste,int))!=0 )
   {
      printf("\n%d",nombre);    
   }
 
   va_end(liste);
}
 
 
 
void main(void)
{
   fonction("toto",1,2,3,4,5,6,7,8,9,0);
}
 
 
Voilà, je crois que c'est à peu près ça...

Reply

Marsh Posté le 22-04-2001 à 17:59:47    

merci pour ces précisions ...
HumanFactor > ce qui m'interresse c'est la partie instruction de la macro. Il me semble que on peut mettre plusieurs instructions sur plusieurs lignes; mais comment. Il semble donc impossible de faire un truc comme ca : chaine1 = chaine2 & chaine3
mais plutot une macro genre : COPY(chaine1,CAT(chaine2, chaine3))
mais la aussi je doute : peut on faire renvoyer une valeur à une macro (ici, CAT reverrait chaine2 concaténée avec chaine3)
            > je voulais pas le mode d'emploi de printf ... mais comment on programme une telle fonction grace au parametre "..." )
 
nnovic > merci pour ton exemple et tes explications. Y'a tout de meme un truc que je pige pas , c'est :
        va_end(liste);
ca sert à quoi ???
je suppose que :
        va_arg(liste,int)
le 2° parametre est le type du parametre ...
donc printf ressemble un peu à ca (a peu pres... dans les tres grandes lignes hein ;)):
 
void printf(char * Description, ...)
{
    int i;
    int Nombre;
    char * Chaine;
    char Caractere;
 
    va_list ListeParam;
 
    va_start(ListeParam,Description);
 
    for(i=0;i<strlen(Description);i++)
    {
        if(Description[i]=='%')
            switch(Description[i+1])
            {
                case 'd' :  
                    Nombre = va_arg(ListeParam,int);
                    if(Nombre==0) return;
 
                    /* code pour afficher un int */
 
                case 's' :
                    Chaine = va_arg(ListeParam,char *);
                    if(Chaine==NULL) return;
 
                    /* code pour afficher une chaine */
 
                case 'c' :
                    Caractere = va_arg(ListeParam,char);
                    if(Caractere==0) return;
 
                    /* code pour afficher un caractere */
            }
    }
}
 
 
cette fonction marcherait selon tes dires ;) pour ces cas :
printf("%d",entier);  
ou  
printf("%s",chaine_caracteres);  
ou  
printf("%c",caractere);  
ou  
printf("%d %s %c %f",entier,chaine_caracteres,caractere,decimal);  
 
mais j'en suis pas convaicu, car dans ton code, si je fait ca :
 
void main(void)  
{  
   fonction("toto",0,1,2,3,4,5,6,7,8,9,0);  
}  
 
eh ben :
    while( (nombre=va_arg(liste,int))!=0 )  
    {  
        printf("\n%d",nombre);    
    }
 
des le debut, nombre vaut 0 et donc ca quitte ...
 
et justement cette macro va_arg m'interresse : elle renvoit un nombre non ???
 
comment on fait, dans une macro, pour renvoyer qq chose ???
et aussi, comment la macro elle fait pour tester le type passé en parametre (elle effectue une comparaison sur la chaine de caratere "int" ou alors y'a un autre moyen ??? => une macro qui fait ca ? :lol:)
 
alors ??? alors ??? repondez-moi, je veux comprendre !!!
:??::??::??::??::??::??::??::??::??::??::??::??::??:

Reply

Marsh Posté le 22-04-2001 à 18:29:27    

Moi-même je connais pas trop l'utilité de va_end(), mais il semblerait que cela évite quand même des plantages.
 
En ce qui concerne le deuxième paramètre de va_arg(), c'est effectivement le type de données en toutes lettres. Ton exemple est donc tout à fait correct.
 
euh, et puis pour le 0, je me suis tout simplement mélangé les pédales. Ce qu'il faut surtout en retenir, c'est qu'il faut savoir à quel moment arrêter de lire les paramètres. Pour cela, soit tu places en dernier un paramètre spécial de fin de liste (un peu comme le caractère '\0' qui marque la fin d'une chaîne de caractère), soit tu passes en argument fixe le nombre d'éléments à lire.
 
Par exemple, tu auras des fonctions qui s'emploieront comme ceci :
 
fonction(3,"arg1","arg2","arg3" );
fonction(quelconque,"arg1","arg2","arg3",NULL);
 
Dans le cas de printf, tu n'as besoin de faire ni l'un ni l'autre, car le nombre d'arguments variables est donné par le format du texte :
 
printf("%d %d",1,2); // les deux %d indiquent qu'il y a deux arguments à lire.
 
Voilà, j'espère que c'est plus clair maintenant ! :)

Reply

Marsh Posté le 22-04-2001 à 18:32:34    

Ah oki dac !
Au fait en parlant de printf ... printk, c'est quoi ???

Reply

Marsh Posté le 22-04-2001 à 18:36:15    

printk ??
Ce n'est pas du C ou du C++ standard en tout cas ! Ou est-ce que tu as rencontré cette fonction ?

Reply

Marsh Posté le 22-04-2001 à 18:42:41    

J'ai étudié differents sources d'OS (des petits genre LittleOS ou + gros comme Linux) et à chaque fois j'ai rencontré printk au lieu de printf ... :??:

Reply

Marsh Posté le 22-04-2001 à 18:50:30    

Désolé, là je ne vois vraiment pas de quoi il s'agit ! :??:
A mon avis, c'est soit une faute de frappe récurrente :P, soit une fonction définie par le programmeur...

Reply

Sujets relatifs:

Leave a Replay

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