IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

[DEBUTANT]Quelques petites mises au point


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut [DEBUTANT]Quelques petites mises au point
    Bonjour à tou(te)s!
    J'ai pas mal avancé dans mon bouquin de C, et j'ai décidé de réaliser un petit jeu du pendu, sans m'aider du bouquin, pour voir ce qui n'allait pas trop. J'attends donc de vous des critiques constructives, des indications sur les mauvaises habitudes que j'ai pu adopter etc.
    pendu.c
    Je n'arrive pas à configurer GCC optimalement (même tout court, tout compte fait!), je n'obtiens aucun warnings, rien du tout...
    Pourquoi le if de ma while principale (ouch!) s'éxecute deux fois??
    Merci à vous, et encore plus si vous prenez le temps de jeter un petit coup d'oeil sur ce bout de code!
    Je n'arrive pas encore à indenter correctement, j'ai fais ce que j'ai pu!

  2. #2
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    ça pars mal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /* Declaration des variables et tableaux */
    char motSecret[10] = "EXACTEMENT";
    et les globales, çaymal.
    compte les lettres... rajoute une place pour le 0 final... et ça fait combien? (moi j'ai 11)

    manque un = je suppose?

    j'ai pas tout lut ... corrige ça, vire tes globales ... et utilise autre chose que scanf ... ça "devrais" marcher.

    pour l'indentation, y'as un petit utilitaire balaize qui s'appelle indent, et qui te fait toute l'indentation

  3. #3
    Membre émérite

    Homme Profil pro
    Inscrit en
    Juillet 2003
    Messages
    2 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 2 075
    Points : 2 844
    Points
    2 844
    Par défaut
    Citation Envoyé par Preez
    Bonjour à tou(te)s!
    Je n'arrive pas à configurer GCC optimalement (même tout court, tout compte fait!), je n'obtiens aucun warnings, rien du tout...
    Pourquoi le if de ma while principale (ouch!) s'éxecute deux fois??
    Merci à vous, et encore plus si vous prenez le temps de jeter un petit coup d'oeil sur ce bout de code!
    Je n'arrive pas encore à indenter correctement, j'ai fais ce que j'ai pu!
    Voilà pour les warnings:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    gcc -Wall -ansi -pedantic /home/gnux/pendu.c -o pendu
    /home/anne/pendu.c:9: warning: data definition has no type or storage class
    /home/anne/pendu.c:9: warning: type defaults to 'int' in declaration of 'ptr_gagne'
    /home/anne/pendu.c: In function 'main'
    /home/anne/pendu.c:36: warning: suggest parentheses around assignment used as truth value
    /home/anne/pendu.c: In function 'lectureCaractere'
    /home/anne/pendu.c:67: warning: ISO C90 forbids mixed declarations and code
    Pour l'indentation, c'est une blague ou c'est vrai? Aujourd'hui tout les éditeurs digne de ce nom propose un mode permettant une indentation correcte. Sinon il y a le programme GNU Indent qui peut le faire pour toi.
    Dans la fonction fgagne() j'utiliserais plutot la structure switch...case

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Points : 631
    Points
    631
    Par défaut
    Les variables globales c'est pas bien, essaye de toujours laisser tes variables internes à tes fonctions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *ptr_gagne = &boolmotSecret[0];
    Pas de type, et ne sert a rien il me semble.

    break dans un if c'est dur la.

    essaye plutot de faire qqch comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int fgagne()
    {
       for(i = 0; i < 10; i++)
           if(boolmotSecret[i] == 0)
               return 0; 
       return 1;
    }
    En C, FALSE vaut 0 et TRUE != FALSE, donc TRUE peut valoir n'importe quoi sauf 0.

    Donc plutot que de tester 200 fois si c'est bien égal à 1 ou pas, considère que tout ce qui n'est pas faux (== 0) est vrai.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut
    D'accord! C'est retenu!
    manque un = je suppose?
    Oui! Et c'est pas faute de me l'avoir dit pourtant, je suis tombé sur beaucoup de mise en garde là-dessus mais bon... Ca deviendra un automatisme plus tard!
    Mon bloc d'affichage du mot caché et de lecture du caractère s'execute toujours deux fois.
    Pour le Scanf, j'étais avec getchar au début, mais je dois pas m'en servir à merveille, ça fonctionnait pas.

  6. #6
    Membre émérite

    Homme Profil pro
    Inscrit en
    Juillet 2003
    Messages
    2 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 2 075
    Points : 2 844
    Points
    2 844
    Par défaut
    Citation Envoyé par Faiche
    Les variables globales c'est pas bien, essaye de toujours laisser tes variables internes à tes fonctions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    *ptr_gagne = &boolmotSecret[0];
    Pas de type, et ne sert a rien il me semble.
    C'est une question d'initialisation de pointeur non? Regarde: http://emmanuel-delahaye.developpez.....htm#pointeurs

  7. #7
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Points : 631
    Points
    631
    Par défaut
    Citation Envoyé par Gnux
    C'est une question d'initialisation de pointeur non? Regarde: http://emmanuel-delahaye.developpez.....htm#pointeurs
    Je voulais juste dire que dans son code, ce pointeur n'est pas déclaré, juste initialisé, et qu'il n'est utilisé nulle part.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut
    Merci Gnux pour les warnings! Merci à tous pour vos réponses aussi rapides.
    Gnux, pour gcc j'ai -Wall -pedantic et -o, tout comme toi, mais je n'ai toujours aucun warnings. Je n'ai pas -ansi...
    J'ai compris pour la fgagne() et TRUE & FALSE, je vais essayer d'arranger ça.
    Pour cette histoire de pointeur, j'étais parti sur une autre idée au départ de l'affaire, et j'ai oublié de supprimer ensuite, je le fais tout de suite!

    Edit: voilà j'ai suivi toutes vos indications et compris mes erreurs.
    Sauf sur un point. Les variables globales, pourquoi "ce n'est pas bien" ou "c'est mal"? C'est quand même le corps du jeu (le motSecret, le caractere etc.).
    Mon corps d'affichage et de saisie du caractere s'execute encore et toujours deux fois,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    while(1) /*Boucle principale*/
    	{
    	    if(!fgagne()) /*Corps du jeu,  (si l'utilisateur n'a pas gagné)*/
    Ca ne viendrait pas du while(1)? Pourtant, le programme est en attente lors du scanf, et ne devrait donc s'executer qu'une fois après la pression sur entrée..

  9. #9
    Membre émérite

    Homme Profil pro
    Inscrit en
    Juillet 2003
    Messages
    2 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 2 075
    Points : 2 844
    Points
    2 844
    Par défaut
    Citation Envoyé par Faiche
    Je voulais juste dire que dans son code, ce pointeur n'est pas déclaré, juste initialisé, et qu'il n'est utilisé nulle part.
    pardon j'ai regardé ça un peu vite mais effectivement. Il est inutile...
    Preez: j'utilise une version standard de gcc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc (GCC) 4.1.0 (SUSE Linux)
    Tu utilises quelle implémentation sur quel système?
    Reposte ton code une fois que tu auras fait les modifs

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Dark_Ebola
    pour l'indentation, y'as un petit utilitaire balaize qui s'appelle indent, et qui te fait toute l'indentation
    Ou A-Style qui est intégré à Code::Blocks...

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut
    Comme compiler j'utilise mingw32-gcc sous Code::Blocks.
    Merci Emmanuel pour A-Style, je vais essayer!

    Edit: j'ai répondu juste avant Gnux.

  12. #12
    Membre émérite

    Homme Profil pro
    Inscrit en
    Juillet 2003
    Messages
    2 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 2 075
    Points : 2 844
    Points
    2 844
    Par défaut
    Citation Envoyé par Preez
    Sauf sur un point. Les variables globales, pourquoi "ce n'est pas bien" ou "c'est mal"? C'est quand même le corps du jeu (le motSecret, le caractere etc.).
    http://emmanuel-delahaye.developpez....s.htm#globales pas mal de choses qui te permettront de comprendre ça.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut
    Et là c'est reglé pour les variables globales???
    Elles sont internes au main à présent?
    pendu.c

    Je me creuse la tête pour cette histoire de répétition de mon bloc central, je n'y comprends rien.
    Pour gcc, c'est Code::Blocks qui n'est pas assez performant, ou ma manière de l'utiliser qui l'est encore moins?

  14. #14
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2006
    Messages
    572
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 572
    Points : 631
    Points
    631
    Par défaut
    Ton code ne compile pas.

    Déclarer une variable en interne veut justement dire qu'elle n'est vue que dans le bloc où elle a été déclarée.

    Je te conseille vraiment de lire un cours complet sur les déclarations de variables.

    Pour que tes fonctions puissent utiliser les variables déclarées, il faut les passer en paramètre.

    Au lieu du while (1) tu devrais mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int quit =0;
     
    while (!quit)
    {
     ...
      if (gagne)
        {
          ...
          quit = 1;
        }
    }
    Comme ça tu sors de ta boucle quand tu as gagné.

    Et puis, pas besoin de faire deux fois le test de la valeur de fgagne, tu connais les deux seules possibilités de retour, cette fonction ne va pas retourner 2 par magie.

  15. #15
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Elles sont locales à main et ne sont donc plus connue des autres fonctions. En conséquence, il faut passer leur valeur en paramètre de ces fonctions :
    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void affiche()
    {
      int i = 0;
      for(i = 0; i < 11; i++)
      {
          if( boolmotSecret[i] == 1)
           printf("%c", motSecret[i]);
          else
           printf("*");
      }
    }
    ne connait pas boolmotSecret ni motSecret. Il faut qq chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void affiche(char *motSecret, int *boolmotSecret)
    {
      int i ;
      for(i = 0; motSecret[i] !=0; i++)
      {
          if( boolmotSecret[i] == 1)
           printf("%c", motSecret[i]);
          else
           printf("*");
      }
    }
    et dans le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Affiche(motSecret,boolmotSecret);

  16. #16
    Membre émérite

    Homme Profil pro
    Inscrit en
    Juillet 2003
    Messages
    2 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 2 075
    Points : 2 844
    Points
    2 844
    Par défaut
    Citation Envoyé par Preez
    Et là c'est reglé pour les variables globales???
    Elles sont internes au main à présent?
    pendu.c

    Je me creuse la tête pour cette histoire de répétition de mon bloc central, je n'y comprends rien.
    Pour gcc, c'est Code::Blocks qui n'est pas assez performant, ou ma manière de l'utiliser qui l'est encore moins?
    Tu as des problèmes avec ton compilateur?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    gcc -Wall /tmp/pendu.c -o pendu
    /tmp/pendu.c: In function 'main'
    /tmp/pendu.c:17: warning: unused variable 'boolmotSecret'
    /tmp/pendu.c:16: warning: unused variable 'caractere'
    /tmp/pendu.c:15: warning: unused variable motSecret
    /tmp/pendu.c: In function affiche
    /tmp/pendu.c:52: error: boolmotSecret undeclared (first use in this function)
    /tmp/pendu.c:52: error: (Each undeclared identifier is reported only once
    /tmp/pendu.c:52: error: for each function it appears in.)
    /tmp/pendu.c:53: error: motSecret undeclared (first use in this function)
    /tmp/pendu.c: In function lectureCaractere
    /tmp/pendu.c:61: error: caractere undeclared (first use in this function)
    /tmp/pendu.c:65: error: motSecret undeclared (first use in this function)
    /tmp/pendu.c:66: error: boolmotSecret undeclared (first use in this function)
    /tmp/pendu.c: In function fgagne
    /tmp/pendu.c:76: error: boolmotSecret undeclared (first use in this function)
    /tmp/pendu.c:80: warning: control reaches end of non-void function
    Ne pas utiliser de variables globales ne signifie pas forcement mettre toutes les variables dans le main(). Tu peux aussi utiliser des constantes sympboliques. Mais cela doit être fait de façon judicieuse

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut
    D'accord je comprends mieux!
    Désolé à tous pour Code::Blocks, j'oublie à chaque fois le "rebuild", le "build and run" lance le programme déjà executé. Ca viendra également, pas d'affolement!
    L'erreur pour les warnings vient également de là, après un rebuild, hop plein de warnings! Merci!

  18. #18
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Preez
    Merci Gnux pour les warnings! Merci à tous pour vos réponses aussi rapides.
    Gnux, pour gcc j'ai -Wall -pedantic et -o, tout comme toi, mais je n'ai toujours aucun warnings. Je n'ai pas -ansi...
    Essaye plutôt ceci :

    -Wall -Wextra -O2
    Edit: voilà j'ai suivi toutes vos indications et compris mes erreurs.
    Sauf sur un point. Les variables globales, pourquoi "ce n'est pas bien" ou "c'est mal"? C'est quand même le corps du jeu (le motSecret, le caractere etc.).
    • Parce qu'on ne sait pas comment ni quand ni qui accède à cette variable. Ca rend le code intestable et incompréhensible. On a aucune certitude sur le code.
    • En plus, ça crée une dépendance, ce qui le rend non modulaire et non réutilisable.
    • Pour finir, l'instance étant unique, ça le rend impropre à la récursion et à l'utilisation dans des threads.

    Par défaut, pas de globales, sauf si la raison est clairement établie (pas d'autre choix possible).
    Mon corps d'affichage et de saisie du caractere s'execute encore et toujours deux fois,
    Cesse une bonne fois pour toutes d'utiliser scanf() (ou apprends à le faire correctement). Les alternatives à base de fgets() ont été maintes fois évoquées...

  19. #19
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Preez
    Et là c'est reglé pour les variables globales???
    Elles sont internes au main à présent?
    Après, il faut commencer à organiser ses données

    Lesquelles sont persistentes ?
    Appartienenent-elles à un bloc fonctionnel ?

    regrouper en structures, passer des adresses de structures aux fonctions... Bref, organiser son code et cesser de coder 'en vrac'...

    Rien de tout celà ne tombe du ciel. Un projet, ça se gère en au moins 3 étapes majeures :

    1 - définition
    2 - conception
    3 - codage.

    sinon, ça reste du bricolage...

  20. #20
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2006
    Messages : 52
    Points : 18
    Points
    18
    Par défaut
    Oui, je me rapelle de ces trois phases (tu m'avais expliqué), mais que c'est dur à mettre en oeuvre...
    Pour les structures, je connais pas encore !
    Bien, alors j'ai utilisé getchar(), mon bloc s'execute toujours deux fois...
    Et si l'utilisateur tape 'E', la fgagne retourne 1 puisque s'affiche à l'écran "Bravo le mot secret était bien E****E*E**", à n'y rien comprendre, le programme marchait mieux au premier jet!
    Qu'est-ce que j'ai fait?:
    pendua.c

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Debutant] Mise au point d'une temporisation
    Par Slivo dans le forum Débuter
    Réponses: 5
    Dernier message: 25/04/2007, 00h18
  2. Réponses: 9
    Dernier message: 17/08/2006, 12h20
  3. [petites questions][debutant]run et mise en forme
    Par kurgan dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 22/10/2005, 17h40
  4. Petite mise au point avec gluUnProject.
    Par fatpat94 dans le forum OpenGL
    Réponses: 1
    Dernier message: 27/07/2005, 15h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo