Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1640 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Difficulté à comprendre un code

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Difficulté à comprendre un code

n°2169077
simius_com​putus
oh Gary boy
Posté le 23-12-2012 à 18:40:19  profilanswer
 

Salut,

 

Dans le chapitre sur les déclarations complexes du K&R, on a cet exemple de programme qui génère la description verbale d'une déclaration :
(il n'est pas présenté exactement comme ça dans le bouquin, j'ai complété/ré-agencé pour essayer de mieux piger)

 
Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #define MAXLEX 100
  5. enum {NOM, PARENS, CROCHETS};
  6. void dcl(void);
  7. void dclabs(void);
  8. int lirelex(void);
  9. int lirecar(void);
  10. void remettrecar(int);
  11. int typelex;
  12. char lex[MAXLEX];
  13. char nom[MAXLEX];
  14. char type[MAXLEX];
  15. char sortie[MAXLEX];
  16. char tamp[MAXLEX];
  17. int ptamp = 0;
  18. main()
  19. {
  20.     while(lirelex() != EOF)
  21.     {
  22.         strcpy(type, lex);
  23.         sortie[0] = '\0';
  24.         dcl();
  25.         if(typelex != '\n')
  26.             printf("erreur de syntaxe\n" );
  27.         printf("%s : %s %s\n", nom, sortie, type);
  28.     }
  29.     return 0;
  30. }
  31. int lirecar(void)
  32. {
  33.     return (ptamp > 0) ? tamp[--ptamp] : getchar();
  34. }
  35. void remettrecar(int c)
  36. {
  37.     if(ptamp >= MAXLEX)
  38.         printf("remettrecar : trop de caractères\n" );
  39.     else
  40.         tamp[ptamp++] = c;
  41. }
  42. int lirelex(void)
  43. {
  44.     int c;
  45.     char *p = lex;
  46.     while((c = lirecar()) == ' ' || c == '\t')
  47.         ;
  48.     if(c == '(')
  49.     {
  50.         if((c = lirecar()) == ')')
  51.         {
  52.             strcpy(lex, "()" );
  53.             return typelex = PARENS;
  54.         }
  55.         else
  56.         {
  57.             remettrecar(c);
  58.             return typelex = '(';
  59.         }
  60.     }
  61.     else if (c == '[')
  62.     {
  63.         for(*p++ = c; (*p++ = lirecar()) != ']'; )
  64.             ;
  65.         *p = '\0';
  66.         return typelex = CROCHETS;
  67.     }
  68.     else if(isalpha(c))
  69.     {
  70.         for(*p++ = c; isalnum(c = lirecar()); )
  71.             *p++ = c;
  72.         *p = '\0';
  73.         remettrecar(c);
  74.         return typelex = NOM;
  75.     }
  76.     else
  77.         return typelex = c;
  78. }
  79. void dcl(void)
  80. {
  81.     int ne;
  82.     for(ne = 0; lirelex() == '*'; )
  83.         ne++;
  84.     dclabs();
  85.     while (ne-- > 0)
  86.         strcat(sortie, " pointeur sur" );
  87. }
  88. void dclabs(void)
  89. {
  90.     int type;
  91.     if(typelex == '(')
  92.     {
  93.         dcl();
  94.         if(typelex != ')')
  95.             printf("erreur : ) manquante\n" );
  96.     }
  97.     else if (typelex == NOM)
  98.         strcpy(nom, lex);
  99.     else
  100.         printf("erreur : on attend un nom ou (dcl)\n" );
  101.     while((type = lirelex()) == PARENS || type == CROCHETS)
  102.         if(type == PARENS)
  103.             strcat(sortie, " fonction retournant" );
  104.         else
  105.         {
  106.             strcat(sortie, " tableau" );
  107.             strcat(sortie, lex);
  108.             strcat(sortie, " de" );
  109.         }
  110. }
 

Exemple : int (*test()) () --> le programme affiche test : fonction retournant pointeur sur fonction retournant int

 

Bon, déjà, la grammaire de ce genre de déclarations, c'est pas facile à appréhender je trouve.
Et concernant le programme, j'arrive pas à analyser l'ensemble du truc. Trop de fonctions qui s'appellent les unes les autres, je ne saisis pas le déroulement.
J'ai essayé de trouver une méthode de schématisation visuelle, sans succès, il me faudrait un grand tableau veleda peut-être, pour arriver à une représentation claire  :D
Essayé de mettre du commentaire partout aussi, mais c'est encore plus fouillis au final.

 

Rien que la méthode avec lirecar() et remettrecar(c), je trouve pas ça naturel, d'emblée ça me met le cerveau en vrac  [:bigorneau magique:5]

 

Donc deux requêtes :
- existe-t-il un moyen efficace de "visualiser" clairement le fonctionnement d'un code non (ou mal) commenté ? Une méthode standard de représentation graphique, avec des boîtes et des flèches je sais pas..
- et bien sûr, si quelqu'un se sent de m'aider à comprendre le code   :jap:  (plusieurs jours que je me prends la tête dessus   [:dobeliou2] )


Message édité par simius_computus le 23-12-2012 à 18:41:32

---------------
IWH  ---  Le forum de toute une génération : http://losersiv.1fr1.net (losers, sans-ami, dépressifs, allez on va faire cette merde)
mood
Publicité
Posté le 23-12-2012 à 18:40:19  profilanswer
 

n°2169098
Profil sup​primé
Posté le 24-12-2012 à 11:27:38  answer
 

Avec un logigramme, bon courage pour la suite.

n°2169107
gilou
Modérateur
Modzilla
Posté le 24-12-2012 à 13:34:05  profilanswer
 

Noter que ce code ne marche pas si les paramètres des fonctions figurent dans la déclaration.
Par exemple, si on a une fonction
int *myf(char *s) {... }
la déclaration puis l'assignation qui suivent sont correctes
int *((*test)(char *));
test = &myf;
mais le code ne sait pas analyser la déclaration int *((*test)(char *))
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2169122
simius_com​putus
oh Gary boy
Posté le 25-12-2012 à 01:53:31  profilanswer
 

Oui, ça fait justement partie des exos proposés par le bouquin : compléter le code.
Mais je peux pas les faire tant que j'ai pas pigé bien le truc de A à Z !
 
Bon là c'est trêve de Nowel  :o  
 
Jovalise, un logigramme, okay je vais googler  :D


---------------
IWH  ---  Le forum de toute une génération : http://losersiv.1fr1.net (losers, sans-ami, dépressifs, allez on va faire cette merde)
n°2169123
gilou
Modérateur
Modzilla
Posté le 25-12-2012 à 02:22:46  profilanswer
 

Ben en fait faut juste que tu t’intéresse a dclabs qui est quasi recursive, au détail près que la récursion passe a travers dcl:  
dclabs fait:
...
if(typelex == '(')
    {
        dcl();
        if(typelex != ')')
            printf("erreur : ) manquante\n" );
    }
...
et  
dcl fait un appel à dclabs:
...
    dclabs();
...
C'est le seul truc un peu complexe du code.
 
On pourrait réécrire dclabs() sans avoir besoin de dcl, la récursion serait plus apparente:

Code :
  1. void dclabs(void)
  2. {
  3.     int type;
  4.     if(typelex == '(')
  5.     {
  6.         int ne;
  7.         for(ne = 0; lirelex() == '*'; )
  8.             ne++;
  9.         dclabs();
  10.         while (ne-- > 0)
  11.             strcat(sortie, " pointeur sur" );
  12.         if(typelex != ')')
  13.             printf("erreur : ) manquante\n" );
  14.     }
  15.     else if (typelex == NOM)
  16.         strcpy(nom, lex);
  17.     else
  18.         printf("erreur : on attend un nom ou (dcl)\n" );
  19.     while((type = lirelex()) == PARENS || type == CROCHETS)
  20.         if(type == PARENS)
  21.             strcat(sortie, " fonction retournant" );
  22.         else
  23.         {
  24.             strcat(sortie, " tableau" );
  25.             strcat(sortie, lex);
  26.             strcat(sortie, " de" );
  27.         }
  28. }


A+,


Message édité par gilou le 25-12-2012 à 02:28:40

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2169144
simius_com​putus
oh Gary boy
Posté le 25-12-2012 à 17:50:40  profilanswer
 

Ah oui ça simplifie déjà les choses, merci. Après j'ai du mal à tracer le tandem lirecar() et remettrecar().
Quand j'aurai assimilé je posterai les solutions que je trouve aux exos du livre.


Message édité par simius_computus le 25-12-2012 à 17:51:18

---------------
IWH  ---  Le forum de toute une génération : http://losersiv.1fr1.net (losers, sans-ami, dépressifs, allez on va faire cette merde)
n°2169151
gilou
Modérateur
Modzilla
Posté le 25-12-2012 à 21:09:38  profilanswer
 

Lirecar c'est tout con, ça lit un caractère de stdin, sauf si tu as stocké des caractères a lire dans un buffer ad-hoc (ptamp) avec remettrecar auquel cas, ça lit dans ce buffer.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2169152
simius_com​putus
oh Gary boy
Posté le 25-12-2012 à 21:28:56  profilanswer
 

Je comprends ce que ça fait, mais naturellement j'aurais mis la saisie dans un tableau, en virant les espaces etc.. Mais ça je suppose que c'est la méthode "bête"  :D


---------------
IWH  ---  Le forum de toute une génération : http://losersiv.1fr1.net (losers, sans-ami, dépressifs, allez on va faire cette merde)
n°2169153
gilou
Modérateur
Modzilla
Posté le 25-12-2012 à 21:50:09  profilanswer
 

Ça serait plus simple, et au lieu de faire remettrecar, il suffirait de reculer le pointeur.  
Ce programme est pas du tout un modèle de qualité. Le seul avantage a faire comme ils font c'est de pas être limité par la taille de l'entrée (ce que ferait un tableau dans lequel on copie), mais vu comment ils se limitent en sortie avec sortie[MAXLEX] euh...
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2169154
simius_com​putus
oh Gary boy
Posté le 25-12-2012 à 23:05:26  profilanswer
 

C'est ce que je me disais aussi !
 
Bonne soirée,


---------------
IWH  ---  Le forum de toute une génération : http://losersiv.1fr1.net (losers, sans-ami, dépressifs, allez on va faire cette merde)

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Difficulté à comprendre un code

 

Sujets relatifs
Afficher correctement du code PHP "littéral"code html généré par googlemap plante frontpage
Recupérer le code lang locale iso 639 (fr_FR) avec std::localeCode VBA (Revue analytique de 2 Balances)
Optimisation code php[JAVA+ HTML5] quelle API utiliser pour la génération de code HTML5 ?
piratage code sourceObfusquer du code javascript
intégration de code html/javascript dans un template[VBA] Optimisation de code
Plus de sujets relatifs à : Difficulté à comprendre un code


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR