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 :

Problème lecture liste chainée


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Problème lecture liste chainée
    Bonjour

    Je souhaite programmer moi même une fonction pop et push.
    Dans un premier temps je fais autant de push que de pop pour eviter toute erreur de chaine vide.

    Cependant le code ci dessous me renvoi toujours le premier élément ajouté.
    Je ne comprends malheureusement pas mon erreur.

    Ma classe

    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
    #ifndef PILE_H
    #define PILE_H
     
     
    class Pile
    {
        public:
            Pile();
            virtual ~Pile();
     
            int valeur; //Valeur de l'element courant
            Pile *prec; //Pointeur sur l'element précedent
     
     
            int Pop(Pile *p);
            void Push(Pile *p, int Val);
     
        protected:
        private:
     
    };
     
    #endif // PILE_H
    Mes fonctions pop et push
    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
     
    int Pile::Pop(Pile *p)
    {
            int Val;
            Pile *tmp=NULL;
     
            tmp = p->prec;
            Val = p->valeur;
     
             /* Le pointeur pointe sur l'element precedent */
            p = tmp;
     
            return Val;     /* Retourne la valeur soutirée de la pile. */
    }
     
    void  Pile::Push(Pile *p, int Val)
    {
            Pile *newelement=NULL;
     
            newelement = new Pile;
            newelement->valeur = Val;
            newelement->prec = p;
     
            p = newelement;
     
     
    }
    Mon main

    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
    #include "Pile.h"
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
        Pile a;
        a.prec=NULL;
        a.valeur=5;
     
        a.Push(&a,6);
        a.Push(&a,7);
        a.Push(&a,8);
     
        cout << a.Pop(&a) << a.Pop(&a) << a.Pop(&a) << a.Pop(&a) <<endl;
        return 0;
    }
    Après exécution j'obtiens 5555

    Si quelqu'un pouvait m'aider à déterminer ce que je fais de travers je lui en serai extrêmement reconnaissant.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Je pense que tu n'as pas tout compris à l'encapsulation en C++.

    Il ne faut pas qu'on puisse accéder aux informations de ta classes sans passer par les méthodes de ta classe.

    Il te faut 2 classes :
    - une classe pile ayant une méthode pop et push ;
    - une classe interne Maillon contenant la valeur à stocker et un pointeur sur l'élément suivant.

    Ce qui donne :
    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
    class Pile
    {
               public :
                       Pile(void);
                       ~Pile(void);
                       Pile(const Pile &);
                       const Pile & operator=(const Pile &);
                       const Type & pop(void);
                       void push(const Type &);
               private :
                       struct Maillon
                       {
                                 Maillon * m_suivant;
                                 Type m_valeur;
                        };
                        Maillon * maillonDebut;
    };
    Ne pas oublier de définir :
    - un destructeur pour libérer tous les maillons alloués ;
    - un constructeur par copie et l'opérateur d'affectation pour éviter que deux piles ai un maillonDebut qui pointe sur un même maillon.

    Sinon, quand tu fais ton pop, il faut supprimer l'élément en tête.

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Oui je n'ai pas mis de getter/setter pour la valeur et le pointeur vers l’élément précédent. L'objectif était pour moi dans un premier temps de faire le programme le plus simple possible pour trouver l'erreur .

    Merci pour m'avoir fais remarquer que j'avais oublier un free ^^

    Pourquoi utiliser une structure dans la classe pile et pas tout simplement deux variables private ?

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Pourquoi utiliser une structure dans la classe pile et pas tout simplement deux variables private ?
    Tu confonds la pile avec un élément de la pile ainsi dès que tu voudra ajouter des données à la pile (taille de la pile, type de pile, etc...), tu va dupliquer ces informations.
    Ensuite, si tu veux insérer/supprimer en tête tu n'as que deux choix :
    - ajouter/supprimer la pile en 2ème position et modifier les valeurs de la 1ere pile ;
    - Détruire la 1ere pile (ou ajouter une pile en tête) et passer un pointeur sur la nouvelle pile en tête

  5. #5
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Ok merci beaucoup pour ces explications, je vais revoir mon code du début

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par franky0 Voir le message
    Oui je n'ai pas mis de getter/setter pour la valeur et le pointeur vers l’élément précédent. L'objectif était pour moi dans un premier temps de faire le programme le plus simple possible pour trouver l'erreur .
    En fait, en informatique, le meilleur moyen de "faire simple" est... de respecter un certain nombre de principes simples.

    Assez paradoxalement, il se fait que, pour faire simple, on doit souvent donner une impression de complexité

    Mais le fait est que l'apparence de complexité ne vient de rien d'autre que de la complexité du besoin que l'on veut couvrir

    Ainsi, il y a un principe qui nous intéresse particulièrement dans cette discussion. On l'appelle couramment SRP pour Single Responsability Principle ou, si tu préfères en français le principe de la responsabilité unique.

    Ce principe pourrait s'exprimer sous la forme de
    Chaque type défini par l'utilisateur et chaque fonction ne doit avoir à s'occuper que d'une seule chose, mais doit s'en occuper correctement
    En effet, le principe d'une pile peut sembler "simple" de prime abord, mais il s'avère néanmoins être beaucoup plus complexe que le concept d'incrémentation, par exemple, qui pourrait s'exprimer dans le fait d'augmenter la valeur d'une variable de 1

    En veux tu la preuve (c'est une question rhétorique, car tu l'auras, que tu la veuilles ou non )

    Si tu devais exprimer le concept de pile, tu l'exprimerais sans doute sous la forme de
    Une pile est un ensemble (ou une collection) d'éléments qui seront gérés selon le principe du "dernier entré, premier sorti" (ou LIFO pour Last In, First Out)
    Si on veut appliquer le rasoir d'ockham pour n'avoir qu'une succession de concepts simples, le simple fait qu'il soit utile de spécifier les deux termes que j'ai mis en évidence suffit finalement à nous prouver que l'on est bel et bien face à un besoin complexe lorsque l'on évoque le concept de pile

    La description d'un élément est malheureusement vachement récursive, mais elle pourrait s'apparenter à quelque chose comme
    Un élément (de collection) est une structure de données permettant de représenter une valeur donnée ainsi que ses relation avec d'autres élément de la collection
    Quant au terme gérés, il peut etre exprimé sous la forme de
    Le fait de pouvoir insérer ou supprimer des éléments de la collection (dans le cas présent, selon le principe du LIFO )
    Encore une fois, tu remarque que le simple concept de "gestion" est un problème complexe, car j'ai, de nouveau, du utiliser deux termes plus simple (insérer et retirer) pour pouvoir l'exprimer.

    Si je voulais d'ailleurs aller jusqu'au bout du raisonnement, je devrais d'ailleurs exprimer clairement ce que j'entends par "ajouter" et par "retirer" un élément, et ce serait sans doute sous la forme de
    Insérer un élément est le fait d'ajouter l'élément en question au bon endroit dans la collection après avoir pris soin de le créer correctement
    Supprimer un élément est le fait de retirer l'élément en question de la collection en veillant à les détruire
    Comme tu peux le constater, il m'a fallu introduire huit termes au total, dont quatre pour lesquels il a fallu que j'exprime clairement ce qu'ils signifiaient pour seulement arriver à exprimer clairement ce que représentait le concept de pile :
    1. éléments que j'ai du expliquer
    2. gérer que j'ai du expliquer
    3. insérer que j'ai du expliquer
    4. supprimer que j'ai du expliquer
    5. ajouter que je n'ai pas expliqué
    6. créer que je n'ai pas expliqué
    7. retirer que je n'ai pas expliqué
    8. détruire que je n'ai pas expliqué
    On peut considérer que ce n'est que quand chaque mot, chaque verbe se suffit à lui-même (de par la définition des mots et des verbes que l'on a utilisé pour les définir), que l'on peut estimer que l'on a appliqué le rasoir d'ockham correctement

    Mais, non seulement, c'est bel et bien la preuve que je t'avais promise : le concept de pile est un concept complexe, mais, en plus, si tu veux faire simple, il faut t'assurer que chaque terme que tu as définis apparaisse dans le code, d'une manière ou d'une autre

    Pour faire simple, tu peux te dire que chaque nom que tu auras du expliquer correspond à un type qu'il te faudra créer et que chaque verbe que tu auras expliqué correspond à une fonction (ou à une fonction membre) qu'il te faudra implémenter.

    Dans le cas présent, la seule exception est le verbe "gérer", car il sera représenté par les fonction "insérer" (push) et "supprimer" (pop)

    Reste, finalement, à déterminer quel verbe (et donc quelle fonction) sera "à usage interne" et quel autre sera "disponible partout" :
    • Ajouter, Créer, Retirer et Détruire n'ont aucune raison d'être accessible "de partout", car ces verbes ne sont utilisés que dans des fonctions particulières, et qu'ils ne correspondent pas à un service que l'on pourrait attendre de la part de la pile.
    • Insérer et Supprimer par contre font partie des services que l'on attend de la part de la pile, et doivent donc "être accessible de partout"
    De même, la notion d'élément en elle même n'a pas besoin d'être disponible depuis n'importe où, "simplement" parce qu'elle intervient dans la gestion interne que l'on peut attendre de la part d'une pile

    C'est en ayant suivi ce principe que Neckara en arrive à ce qui te semble "bien complexe" et qui, pourtant, correspond à "la manière la plus simple" qui permet d'implémenter le concept de pile
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Hello j'ai recommencer en utilisant le principe de la structure dans la classe.
    Ça marche nickel et c'est effectivement beaucoup plus logique ^^

    Merci pour vos reponses rapides

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de liste chainée
    Par SPACHFR dans le forum Débuter
    Réponses: 2
    Dernier message: 09/09/2009, 15h39
  2. Problème fabrication liste chainée
    Par scary dans le forum Débuter
    Réponses: 2
    Dernier message: 10/03/2009, 12h04
  3. Problème de listes chainées
    Par line86 dans le forum C
    Réponses: 5
    Dernier message: 20/04/2008, 10h30
  4. Probléme avec Liste Chainée
    Par Lucas42 dans le forum C
    Réponses: 6
    Dernier message: 24/01/2008, 20h15
  5. un probléme de liste chainé simple
    Par seifdev dans le forum C
    Réponses: 15
    Dernier message: 02/04/2007, 16h36

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