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 :

ces pointeurs qui me hantent


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut ces pointeurs qui me hantent
    salut,


    voila, je débute, je suis étudiant en info et je ne comprends rien a ces pointeurs et tout ce qu'ils engendre (liste chainée, pile, file, arbre)

    genre une fois que le prof fais "bloc *tete" ou "bloc **tete" je suis depassé et aussi par tout ces element->suivant et element *valeur

    le seul truc que j'ai compris c'est au début c'est la declaration genre une strcture avec un element et un ou 2 pointeurs...

    ce que je veux, c'est une documentation claire et net sur tout ça si c'est possible car je suis déja en retard par rapport au groupe

    merci a tous

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Un pointeur, c'est l'adresse mémoire d'un objet.
    Une liste chaînée simple, c'est un ensemble de blocs {valeur, adresse du bloc suivant} qui sont chaînés.
    C'est tellement simple qu'il n'y a rien à dire de plus...

  3. #3
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut
    ben ça parait simple et je le comprend dis comme ça mais c'est pas aussi facile que ça en a l'air...

    il y a des opérations a effectué sur ces structures a qui je ne comprend rien...bref !!

    un coup de main ou une documentation ne sera pas de refus

  4. #4
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Et voilà !

    http://chgi.developpez.com/pointeur/
    D'ailleurs, tu trouveras sur DVP.com tout un tas de tutoriels, FAQ et cours sur le C++ (voir lien en haut du forum).

    Bonne continuation ,

    Poukill

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    On peut essayer de te faire comprendre les choses sous l'angle suivant:

    Tu t'en doutes surement (à défaut de dire tu le sais ), tout ce que tu manipule se trouve toujours "en mémoire", le terme mémoire étant pris dans sa plus large acception.

    La mémoire est "adressée", c'est à dire que, chaque "bloc mémoire" disponible peut être représenté par une "adresse" (en fait un simple numéro d'ordre).

    Pour accéder à l'informaiton contenue dans un bloc mémoire, deux solution nous sont données:

    La plus simple est de déclarer une variable à laquelle nous accéderons en utilisant son nom (son "identifiant").

    La deuxième, un peu plus complexe (mais pas énormément) est d'y accéder en donnant... l'adresse mémoire, ou plus souvent, en indiquant qu'il faut aller "chatouiller" "ce qui se trouve à l'adresse untel".

    Un pointeur n'est qu'une variable particulière dans le sens où l'information qu'elle contient est... l'adresse à laquelle nous trouverons l'information réellement recherchée.

    Pour indiquer au compilateur que nous voulons utiliser un pointeur, nous plaçons un astérisque entre le type de la variable et son nom.

    Ainsi, un pointeur sur un entier nommé b sera déclaré sous la forme de
    Cela signifie que b est une variable qui contient... l'adresse à laquelle nous trouverons un entier.

    Mais comme un pointeur peut n'être considéré en définitive que comme une variable, particulière certes, on peut envisager de vouloir travailler avec... l'adresse à laquelle se trouve cette variable et créer un... pointeur de pointeur (il "suffit" de rajouter un astérisque, ce qui donne Type ** PdePointeur), qui peut lui-même n'être considéré que comme une variable (particulière) sur laquelle on peut envisager de... Et ainsi de suite...

    Je ne sais pas si la norme prévoit une limite dans le nombre, mais, il faut avouer que, au delà de deux ou trois (pointeur de pointeur ou pointeur de pointeur de pointeur), cela devient franchement difficile à gérer

    Puis, reste le problème de "comment manipuler ces bidules"...

    Il y a plusieurs cas à envisager:

    Vu qu'un pointeur représente "l'adresse à laquelle se trouve une variable", il semble cohérent d'être en mesure... de récupérer l'adresse de la variable

    Cela se fait en ajoutant l'esperluette "&' devant la variable, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int a = 10; // une variable "simple" de type entier
    int * b;    // un pointeur sur un entier;
    b = &a;     // assignons au pointeur l'adresse à laquelle se trouve la variable
                // a
    De même, si un pointeur représente l'adresse d'une variable, il semble tout aussi cohérent d'être en mesure de... récupérer la variable.

    Nous demandons d'accéder "à ce qui est pointé par notre pointeur" en ajoutant l'astérisque devant le nom du pointeur, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int a = 10; // une variable "simple" de type entier
    int * b;    // un pointeur sur un entier;
    b = &a;     // assignons au pointeur l'adresse à laquelle se trouve la variable
                // a
    *b = 12     // assignons 12 à "ce qui est pointé par b" (autrement dit, à a :P)
    En outre, il faut savoir que les pointeurs sont souvent utilisés dans un contexte de "gestion dynamique de la mémoire".

    En effet, les variables souffrent d'un "problème" qu'il est bon de pouvoir contourner: elle sont "détruites" dés que l'on quitte la portée dans laquelle elles sont déclarées.

    Or, il arrive régulièrement que l'on souhaite pouvoir être seul juge du moment où la mémoire est réellement assignée à une variable et du moment où cette mémoire est effectivement libérée "pour un usage ultérieur".

    Nous pouvons donc "prendre la responsabilité de la gestion de la mémoire" en le demandant expressément lors de l'allocation de... la mémoire allouée à une variable. Cela se fait avec le mot clé new.

    Il ne faut alors pas oublier de libérer expressément cette mémoire quand la variable devient inutile avec le mot clé delete.

    Cela prend donc souvent une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Type * ptr = new Type; // allocation dynamique de la mémoire nécessaire
                           // pour contenir un objet Type
    /*utilisation de notre objet */
    delete ptr; // quand l'objet devient inutile, on libère la mémoire qui lui est
                // allouée
    Cela nous permet, en outre, de demander d'allouer directement la mémoire nécessaire pour représenter un nombre (finalement quelconque, tant qu'on dispose de suffisamment de mémoire) d'objets de manière contigüe en mémoire.

    Il suffit d'indiquer le nombre d'objet que l'on souhaite entre crochets, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type * ptr = new Type[nombre_d_objets_souhaité] ;
    Dans ce cas, l'adresse contenue par ptr sera l'adresse à laquelle on trouve le premier élément des (nombre_d_objets_souhaité)

    La seule différence est qu'il faudra alors prévenir que l'on souhaite libérer la mémoire allouée à un tableau d'objets contigus en mémoire en ajoutant les crochets au mot clé delete:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Type * ptr = new Type[nombre_d_objets_souhaité] ; 
    /* utilisation de ptr */
    /* et libération de la mémoire qui y est allouée quand on n'en a plus
     * besoin
     */
    delete[] ptr;
    Il reste, pour finir, un dernier point à aborder au sujet des pointeurs: l'arithmétique des pointeurs.

    En effet, on peut déclarer un pointeur sur... strictement tout et n'importe quoi.

    Et je ne te ferai pas l'affront de sous entendre que tu n'a pas conscience que la mémoire nécessaire pour représenter un objet dépend directement... des informations qu'il contient.

    Hé bien, l'avantage, c'est que, si tu incrémente un pointeur (ptr++) ou que tu le décrémente (ptr--), tu n'as pas à t'inquiéter de la taille réellement utilisée en mémoire par l'objet pointé: ton pointeur prendra comme valeur l'adresse du prochain (ou du précédent, en cas de décrémentation) objet du type en cours de traitement.

    C'est à dire que si Type prend - par exemple - 140 bytes, et que tu as un pointeur de sur Type, le fait de l'incrémenter fera que l'adresse contenue dans le pointeur sera... 140 bytes supérieure à l'adresse d'origine.

    Et, fatalement, si tu le décrémente, l'adresse contenue dans le pointeur sera... 140 bytes inférieure à l'adresse d'origine.

    Cela signifie qu'avec un type (quelconque), tu pourrais envisager un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Type * ptr = new Type[10];
    ptr++; // passe à l'élément de type Type
    Sauf que tu perd alors l'adresse du premier élément, et que c'est sur cette adresse là qu'il s'agit d'invoquer delete[]...

    C'est la raison pour laquelle, si tu dois modifier l'adresse représentée par un pointeur, il vaut mieux... utiliser un autre pointeur pour ne pas perdre l'adresse d'origine.
    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

  6. #6
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut
    merci, j'ai déja lu ces tutos et je le comprends


    moi mon probleme se pose au niveau de l'utilsation surtout (liste, file,pile,arabre)..et tous les oparation qui vont avec (inserction,susspenssion,recherche et autres)...

  7. #7
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    ce que je veux, c'est une documentation claire et net sur tout ça si c'est possible car je suis déja en retard par rapport au groupe
    En général dans ces cas là c'est bien d'en discuter avec les autres. Ils ont le même "background" que toi, et peuvent surement mieux comprendre tes problèmes que nous. Beaucoup de problèmes peuvent être résolus en interne par des discussions entre camarades!
    On t'a donné des liens vers des tutos, Koala t'a écrit un roman. Sans exemple particulier de ta part d'un cas précis que tu ne comprends pas, je vois pas ce qu'on peut faire de plus...

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Les concepts de pile, file, liste, arbre sont des concepts pourtant basique, et qui explique clairement ce qu'ils permettent:

    La pile ressemble à la pile de caisses: tu rajoute une caisse sur le sommet de la pile, et, quand tu veux en retirer une, tu ne peux retirer que celle qui est sur le sommet, sous peine de toutes te les ramasser sur le coin de la figure (système LIFO)

    La file, c'est ce que l'on remarque lorsqu'on s'apprète à payer dans un magasin: le premier près de la caissière sera le premier à payer... (système FIFO)

    La liste permet de "trier" les élément: il arrive souvent, lorsque tu n'a qu'une barre de chocolat, qu'une gentille personne te permette de passer devant elle, et d'atteindre plus vite la caissière

    Enfin, l'arbre binaire consiste à suivre un chemin différent selon que l'objet recherché est plus grand ou plus petit que l'objet qui te sert de comparaison: cela implémente la recherche "dichotomique"

    Une fois que tu sais cela, il te "suffit" de séparer ta "collection" (pile, file, liste, arbre binaire) de son contenu (élément ou noeud) et le contenu... de l'objet réel à manipuler

    Tu pars donc d'une structure proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct MyStruct
    {
        /* les variables "qui vont bien" entre elles */
    };
    Comme tu veux gérer une collection d'objet, tu va créer un élément de ta collection, selon le cas, cela donnera
    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
    struct Node
    {
        MyStruct s; // il faut pouvoir disposer de l'objet à manipuler :D
        /* pour une pile */
        Node* previous; // permet de récupérer l'élément précédent dans la pile
        /* pour une file */
        Node* next; //permet de récupérer l'élément suivant dans la pile 
        /* pour une liste, ca va de */
        Node* next; /* une liste "simplement chainée */
        /* à, pour une liste "doublement chainée" */
        Node* next; // acces à l'élément suivant
        Node* previous; // acces à l'élément suivant
        /* et enfin, pour l'arbre binaire */
        Node* parent; //acces à l'élément parent
        Node* lesser; // acces à l'élément plus petit
        Node* greater; //acces à l'élément plus grand
    };
    Et enfin, tu crée ta collection en y placant, de toutes manières, au moins un pointeur de type Node, en y ajoutant éventuellement quelques variables qui permettent de compter le nombre de noeud présents, et les méthodes "qui vont bien" pour pouvoir gérer correctement les éléments un à un ou l'ensemble des élément qu'elle contient (sur base du type de collection que tu envisage)
    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

  9. #9
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 12
    Par défaut
    merci beaucoup, je vais voir tous ça de prêt cette ce soir ^^

Discussions similaires

  1. Ces chaînes qui se déchainent.
    Par peijnoob dans le forum C
    Réponses: 12
    Dernier message: 24/10/2006, 13h04
  2. [MFC] Accès pointeur qui donne rien :s
    Par EagleEye dans le forum MFC
    Réponses: 3
    Dernier message: 02/03/2006, 19h32
  3. Un pointeur qui n'en fait qu'a sa tête...
    Par Zenol dans le forum C++
    Réponses: 10
    Dernier message: 11/09/2005, 17h40
  4. Réponses: 8
    Dernier message: 04/08/2004, 15h17
  5. [MFC] Ces fenêtres qui ne s'affichent pas..
    Par Davide dans le forum MFC
    Réponses: 3
    Dernier message: 19/11/2003, 12h30

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