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 :

Surement sur les pointeurs


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Surement sur les pointeurs
    Bonjour ou plutot Bonsoir a cette heure-ci, je suis tout nouveau ici =)), c'est un ami qui ma fais decouvrir ce site, et je trouve qu'il ma beaucoup aidé.

    Donc j'expose mon probleme:=> Debutant que je suis,j'ai voulu concevoir un pti premier programme sur le pendu, ainsi j'ai etudié les pointeurs
    Voici mon code, et excusez moi d'avance si mon programme n'est pa tres propre

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
     
    char * init_mot(){
     
      srand(time(NULL));
      int i=0;
     
      char *p_mot ;
      char *tab[3]={"bonjour","aurevoir","abientot"};
      p_mot = tab[rand()%3];
     
      /* for ( i=0; i<strlen(p_mot);i++){
         printf("%c",p_mot[i]);
         }
      */
     
      return p_mot;
    }
     
    char * init_jeu(char *mot){
     
      char *p_devine;
      char devine[32];
      int longueur;
      int i=0;
     
      p_devine = &devine;
      longueur = strlen(mot);
     
      printf("Voici le mot que tu dois deviner ===>\t");
     
      for(i=0;i<longueur;i++){
        devine[i]='_';
        printf("%c",devine[i]);
      }
      printf("\n");
      return p_devine;
    }
     
    void jouer(char *mot, char *devine, int longueur){
     
      int i=0;             // variable de boucle
      char lettre;         // variable lettre entre
      int nb=0;            // variable lettre presente ds le mot
      int err=3;           // cpt d erreur
      int var=0;           // cpt gain
     
      /* for (i=0;i<longueur;i++){
         printf("%c",devine[i]);
         }
      */
     
     
      do
        {
          nb=0;
          printf("\n rentre une lettre\n");
          scanf("%c",&lettre);
          getchar();
     
          //printf("tu as rentré un %c\n",lettre);
     
     
          for(i=0;i<longueur;i++){
     
    	if(mot[i] == lettre){
     
    	  *(mot+i)=*(devine+i);
    	  *(devine+i)=lettre;
    	  nb++;
    	  //printf("%c",mot[i]);
    	}
          }
     
          var+=nb;
     
          if(nb == 0 ){
    	err--;
    	printf("Il te reste encore %d chances\n",err);
          }
     
          for (i=0;i<longueur;i++){
    	printf("%c",devine[i]);
          }
     
        }
      while(var<longueur && err>0);
     
      if(err == 0)
        printf("T une chips \n");
      else
        printf("T un winner\n");
     
    }
     
     
     
    int main(){
      char *devine;
      char *mot;
      mot = init_mot();
      printf("\n");
     
      devine = init_jeu(mot);
      int longueur= strlen(mot);
      //printf("%d",longueur);
     
      jouer(mot,devine,longueur);
     
      return 0;
    }
    J'ai testé mon programme et mon probleme est que dans ma fonction jouer a l'exterieur de mon do while mes pointeurs pointent bien sur la bonne zone memoire en revanche a l'interieur mon pointeur pointe sur n'importe koi ?_?


    Voila j'espere j'ai été assez clair dans mes propos en esperant un peti coup de pouce de votre part merci d'avance

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Bonsoir

    Je me lance


    Tu renvoies dans init_mot ( suis pas allez plus loin) l'adresse d'une variable qui est locale. Ce qui signifie qu'une fois sorti de la fonction cette variable n'existe plus ( ce qui est le cas de toute les variables définis dans une fonction [dans un bloc {} en fait]exceptées celles déclarées static). Tu dois copier ce qu'elle retourne dans une autre variable ( fonction strcpy);

    srand(time(NULL)); peut être effectué dans la fonction main. Cette fonction ne doit être appelée qu'une seule fois. Comme je suppose qu'en extension init_mot sera appelé plusieurs fois ( plusieurs parties), tu risques donc de le faire plusieurs fois

    On pourrait réduire init_mot et écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char * init_mot(){ 
    static char *tab[3]={"bonjour","aurevoir","abientot"}; 
    return tab[rand()%3]; 
    }
    Je sens que emmanuel va me taper sur les doigths ( hihihi)
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    merci d'avoir repondu =p
    je sais que es variables sont locales a la fonction
    mais je crois que j'ai fais ce que tu as di dans le main
    ie j'ai declaré un pointeur et je l'ai initialisé avec la valeur rendu
    de la fonction init_mot()

    J'ai testé et ce n'est que cette partie de mon code qui pose probleme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    for(i=0;i<longueur;i++){
     
    	if(mot[i] == lettre){
     
    	  *(mot+i)=*(devine+i);
    	  *(devine+i)=lettre;
    	  nb++;
    	  //printf("%c",mot[i]);
    	}
          }

  4. #4
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Sans chercher bien longtemps, les choses suivantes sont fausses. Avant d'aller plus loin, corrige donc tout ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char *p_mot ;
     char *tab[3]={"bonjour","aurevoir","abientot"};
     p_mot = tab[rand()%3];
     <...>
     return p_mot;
    Variable locale à la fonction. N'existe plus à la sortie => utilise malloc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char * init_jeu(char *mot){
     
    char *p_devine;
    char devine[32];
    int longueur;
    int i=0;
     
    p_devine = &devine;
    p_devine est de type char * ; &devine est de type char **.
    Par ailleurs, dans la même fonction, tu fais :
    Outre le fait de l'assignation fausse, tu retournes encore une adresse qui ne sera plus valide en sortant de la fonction.

    Quant aux erreurs dans la fonction jouer, je n'ai pas regardé, mais avec des parametres faux, de toute façon, ça ne risque pas de fonctionner
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  5. #5
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Pouic >> pour ta première remarque, je serais moins affirmatif que toi, en effet dans ce cas présis, p_mot renvoie l'adresse d'une chaîne écrite en dur, donc vraisemblablement située dans une zone particulière de la mémoire, et il est possible que cette adresse survive à la sortie de la fonction.
    Par contre, si j'ai bien suivi le déroulement du programme, cette chaîne est modifiée donc il y a toute chance que ça plante à un moment.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Trap D: +1

    C'est pourquoi je conseillerais:
    • Si le compilo est GCC, d'activer -Wwrite-strings
    • De remplacer les char * par des const char * là où il faut
    • de faire un strdup() sur la chaîne quand on a besoin de la modifier (ne pas oublier le free())
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    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 Re: Bonjour Debutant Need Help Plz (surement sur les pointeu
    Citation Envoyé par PimsOrange
    Voici mon code, et excusez moi d'avance si mon programme n'est pa tres propre
    Ton code ne compile pas. et il rend mon compilateur très bavard :
    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
    18
    19
    20
    21
    22
    23
     
    Compiling: main.c
    main.c:6: warning: function declaration isn't a prototype
    main.c: In function `init_mot':
    main.c:8: warning: passing arg 1 of `srand' as unsigned due to prototype
    main.c:12: warning: initialization discards qualifiers from pointer target type
    main.c:12: warning: initialization discards qualifiers from pointer target type
    main.c:12: warning: initialization discards qualifiers from pointer target type
    main.c:9: warning: unused variable `i'
    main.c: At top level:
    main.c:23: warning: no previous prototype for 'init_jeu'
    main.c: In function `init_jeu':
    main.c:30: warning: assignment from incompatible pointer type
    main.c:31: error: implicit declaration of function `strlen'
    main.c:31: warning: nested extern declaration of `strlen'
    <internal>:0: warning: redundant redeclaration of 'strlen'
    main.c: At top level:
    main.c:43: warning: no previous prototype for 'jouer'
    main.c: In function `main_':
    main.c:108: warning: nested extern declaration of `strlen'
    <internal>:0: warning: redundant redeclaration of 'strlen'
    Process terminated with status 1 (0 minutes, 0 seconds)
    1 errors, 11 warnings
    Pas de Wi-Fi à la maison : CPL

  8. #8
    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 hegros
    Tu renvoies dans init_mot ( suis pas allez plus loin) l'adresse d'une variable qui est locale.
    Comment ? L'adresse retournéee est celle d'une chaine statique, il n'y a aucun danger.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char * init_mot(void)
    {
       srand((unsigned)time(NULL));
     
       char *tab[3] = {"bonjour", "aurevoir", "abientot"};
       char *p_mot = tab[rand() % 3];
     
       return p_mot;
    }
    Par contre, l'adresse pointant sur une zone non modifiable, l'usage du qualificateur const est fortement conseillé.
    On pourrait réduire init_mot et écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char * init_mot(){ 
    static char *tab[3]={"bonjour","aurevoir","abientot"}; 
    return tab[rand()%3]; 
    }
    Je sens que emmanuel va me taper sur les doigths ( hihihi)
    Ben oui. Le static est inutile. C'est pas tab qu'on retourne, mais tab[x] qui est l'adresse d'une variable statique.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char const * init_mot(void)
    { 
       char const *tab[] = {"bonjour", "aurevoir", "abientot"}; 
       return tab[rand()% (sizeof tab / sizeof *tab)]; 
    }
    Pas de Wi-Fi à la maison : CPL

  9. #9
    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 PimsOrange
    merci d'avoir repondu =p
    je sais que es variables sont locales a la fonction
    mais je crois que j'ai fais ce que tu as di dans le main
    ie j'ai declaré un pointeur et je l'ai initialisé avec la valeur rendu
    de la fonction init_mot()

    J'ai testé et ce n'est que cette partie de mon code qui pose probleme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    for(i=0;i<longueur;i++){
     
    	if(mot[i] == lettre){
     
    	  *(mot+i)=*(devine+i);
    	  *(devine+i)=lettre;
    	  nb++;
    	  //printf("%c",mot[i]);
    	}
          }
    Tu modifies (via des pointeurs) des chaines non modifiables. Comme il s'agit du mot à deviner et ça ne devrait pas arriver, je pense qu'il y a un bug dans ton algorithme.

    Pourquoi dans la même fonction et pour le même objet, utiliser les notations 'mot[i]' et '*(mot+i) ' ? C'est pas très cohérent. (La première à ma préférence).
    Pas de Wi-Fi à la maison : CPL

  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 Trap D
    Pouic >> pour ta première remarque, je serais moins affirmatif que toi, en effet dans ce cas présis, p_mot renvoie l'adresse d'une chaîne écrite en dur, donc vraisemblablement située dans une zone particulière de la mémoire, et il est possible que cette adresse survive à la sortie de la fonction.
    Il s'agit d'une chaine constante, qui par définition est de durée de vie 'statique' (permanente) (static duration)
    Par contre, si j'ai bien suivi le déroulement du programme, cette chaîne est modifiée donc il y a toute chance que ça plante à un moment.
    Exact.
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Membre éprouvé
    Avatar de Pouic
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 669
    Points : 977
    Points
    977
    Par défaut
    Citation Envoyé par Trap D
    Pouic >> pour ta première remarque, je serais moins affirmatif que toi, en effet dans ce cas présis, p_mot renvoie l'adresse d'une chaîne écrite en dur, donc vraisemblablement située dans une zone particulière de la mémoire, et il est possible que cette adresse survive à la sortie de la fonction.
    Oulà, oui, tu as raison...

    (* m'apprendra à corriger du code à 2h du mat'...*)
    Software becomes slower faster than hardware becomes faster
    [size=1]
    http://xrenault.developpez.com

  12. #12
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Ca m'apprendra aussi de répondre si tard
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  13. #13
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3
    Points : 1
    Points
    1
    Par défaut re
    tout d'abord C noté pour la balise code =)
    ensuite je vous avoue que je suis un peu perdu avec la variable static

    pour mon algo:
    Je voulais interchangé les caractere un a un a chaque fois qu'une lettre est trouvé
    je m'explique, par exemple je prend le mot bonjour que la fonction init_mot le rend sous forme static je créé une variable locale au main que je lui affecte qui par la suite sera modifiable (enfin C ce ke je pensais mais bon je vois que ce n'est pa le cas)
    et init_jeu() permet de créé devine[]qui contient 7 '_'
    ensuite imaginons je rentre un 'b' qui sera stocker dans lettre, je parcours ma chaine de caractere mot[] et a chaque fois que je rencontre un 'b' je l'intervertie avec devine[i] car i corespond a l'index exacte pour les 2 chaine de caractere et ensuite j'affiche devine[i]

    oula c un peu long -_-, c la premiere idéé qui m'est venu en tete pour l'algo si vous avez plus simple je vous prie de bien vouloir m'indiquer la voie =p

    merci pour vos reponses



    P.S: j'utilise devC++ chez moi pour compiler a la faq le compilateur criais plus mais avec devC++ il m'affiche un seul warning faut-il que je change de compilo ? si oui lequel ?

  14. #14
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Il faut surement que tu changes les réglages du compilo, mais n'utilisant pas Dev C++ je ne peux pas te les indiquer.
    Tes idées n'étaient pas mauvaises, simplement, il faut faire des copies des chaînes en dur (avec strdup par exemple, attention aux conditions d'utilisation) , sinon tu ne peux pas les modifier, c'est tout.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

Discussions similaires

  1. [Debutant] Nouvelle question sur les pointeurs
    Par etiennegaloup dans le forum Débuter
    Réponses: 3
    Dernier message: 11/01/2006, 09h55
  2. Question sur les pointeurs.
    Par Chrisemi dans le forum C++
    Réponses: 5
    Dernier message: 28/10/2005, 23h47
  3. Dev c++ en rade sur les pointeurs ?...
    Par Magicien d'Oz dans le forum C
    Réponses: 17
    Dernier message: 13/10/2005, 19h38
  4. questions sur les pointeurs
    Par Hyoga dans le forum C++
    Réponses: 17
    Dernier message: 08/01/2005, 23h25
  5. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50

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