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 :

Struct liste chainée et pointeur


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 66
    Points : 49
    Points
    49
    Par défaut Struct liste chainée et pointeur
    Bonsoir,

    J'ai un petit problème de compréhension sur une structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    typedef struct EPOINT EPOINT; 
     
    struct EPOINT {
      double x;
      double y;
      struct EPOINT *next;
    };
     
    typedef EPOINT *PLISTE;
    Alors je connais le principe des listes chainées, mais c'est juste au niveau des "typedef" que j'ai du mal à comprendre.

    Quelle est la différence entre "typedef struct EPOINT EPOINT; " et "typedef EPOINT *PLISTE;" ?

    Est-ce qu'avec PLISTE je peux accéder aux différents éléments avec des indices comme un tableau ?

    Merci.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour,

    Citation Envoyé par hotman1313 Voir le message
    Alors je connais le principe des listes chainées, mais c'est juste au niveau des "typedef" que j'ai du mal à comprendre.

    Quelle est la différence entre "typedef struct EPOINT EPOINT; " et "typedef EPOINT *PLISTE;" ?
    Il faut d'abord savoir qu'une liste chaînée n'est pas un type natif en soi, mais une structure de données, c'est-à-dire une manière de les organiser, au même titre qu'une pile ou un buffer.

    En fait, c'est plus clair présenté ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        typedef   struct EPOINT        EPOINT;
        typedef   EPOINT *             PLISTE;
    Autrement dit, « struct EPOINT » est renommé (ou plutôt bénéficie d'un alias) en « EPOINT » tout court, puis « PLISTE » devient équivalent à « EPOINT * ». Ça veut dire que le pointeur est caché derrière son alias mais qu'il existe toujours en tant que tel.

    C'est une très mauvaise pratique mais elle est malheureusement extrêmement répandue dans les cours d'algorithmique quand on étudie ces structures là.

    Est-ce qu'avec PLISTE je peux accéder aux différents éléments avec des indices comme un tableau ?
    Non. C'est d'ailleurs le principe de la liste chaînée, (sauf foncteurs et assimilés dans d'autres langages). Chaque élément (les maillons de la chaîne) contient une donnée utile et une référence vers le prochain maillon (en C, sous forme de pointeur). Ça te permet d'insérer et de supprimer très facilement des éléments, voire des morceaux de chaîne entiers mais en contrepartie, tu perds l'accès aléatoire : il redevient séquentiel et tu es obligé de parcourir la liste pour retrouver un élément donné. Tu peux cependant optimiser la chose en conservant les références vers les maillons utiles.

  3. #3
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    J'ajoute qu'il faut bien comprendre que les typedef ne correspondent pas à des instructions exécutables et qu'il n'ont aucune incidence sur le code généré. C'est une fonctionnalité offerte au programmeur pour s'éviter de retaper des noms de types fastidieux et/ou pour améliorer la lisibilité de son code.


    Citation Envoyé par Obsidian Voir le message
    puis « PLISTE » devient équivalent à « EPOINT * ». Ça veut dire que le pointeur est caché derrière son alias mais qu'il existe toujours en tant que tel.

    C'est une très mauvaise pratique mais elle est malheureusement extrêmement répandue dans les cours d'algorithmique
    +1 c'est vraiment dégueulasse..

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 66
    Points : 49
    Points
    49
    Par défaut
    Bien, merci pour ta réponse très clair.

    Dans le header qu'on nous a donné, il y a une déclaration de fonction assez ambigüe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /*
     * Initialisation avec un point
     * INPUT: coordonnees du point
     * OUTPUT: pointeur sur liste creee
     */
    PLISTE init_liste(double xx, double yy);
    D'après le commentaire, la fonction doit retournée un pointeur. Soit l'étoile a été oubliée, soit j'ai mal compris.
    Du coup, voici mon code tel que je l'ai compris :

    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
     
    /*
     * Initialisation avec un point
     * INPUT: coordonnees du point
     * OUTPUT: pointeur sur liste creee
     */
    PLISTE *init_liste(double xx, double yy){
    	//inits
    	PLISTE *uneListeP;
    	EPOINT *p;
     
    	//allocation
    	uneListeP = malloc(sizeof(PLISTE));
    	p = create_point(xx, yy, NULL);
     
    	//affectations
    	uneListeP[0] = p;
     
    	return uneListeP;
    }
    J'ai également ajouté l'étoile dans le header. En effet, cela me paraissait plus logique, mais je pense avoir mal compris.

    Merci.

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    typedef EPOINT *PLISTE; : cette ligne informe l'analyseur lexical que chaque fois qu'il rencontre le terme PLISTE, il doit le remplacer par EPOINT * (pas EPOINT). Tu peux voir cela comme un « #define amélioré ». C'est complètement équivalent à :
    • typedef EPOINT* PLISTE;
    • typedef EPOINT * PLISTE;
    • typedef EPOINT <whitespace> * <moar whitespace..> PLISTE ;
    • etc...


    Ici PLISTE « implique » donc déjà l'astérisque, c'est un type pointeur. Si tu ajoutes une astérisque, tu transformes ce type en EPOINT **.

    Cette incompréhension est ce pourquoi nous écrivions avec Obsidian qu'il ne faut jamais définir d'alias sur un type pointeur, en particulier lorsque l'on s'adresse à des débutants.

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2012
    Messages : 66
    Points : 49
    Points
    49
    Par défaut
    Merci je comprends mieux.
    Oui j'imagine que cette syntaxe n'est pas bonne, mais elle nous a été donnée tel quelle est.

    Je passe en résolu.

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    La syntaxe est bonne, puisque ca compile. Par contre, c'est un piège pour l'humain qui doit développer, car il y a une étoile cachée
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #8
    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 519
    Points
    41 519
    Par défaut
    D'un autre côté, ça peut rester intéressant pour donner un type opaque à l'utilisateur (ex: tous les Hxxxxx de Windows).
    Mais en revenant du premier côté, on peut très bien faire ça sans supprimer le pointeur (ex: les FILE* du C).
    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.

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

Discussions similaires

  1. Double pointeurs dans les listes chainées
    Par NouK32 dans le forum Débuter
    Réponses: 8
    Dernier message: 10/02/2008, 18h19
  2. Réponses: 18
    Dernier message: 29/03/2007, 20h40
  3. [Débutant] Pointeur sur liste chainée
    Par HaTnuX dans le forum C
    Réponses: 2
    Dernier message: 02/12/2006, 17h53
  4. Liste chainée et pb de pointeur
    Par P'tite Nélodie dans le forum C
    Réponses: 9
    Dernier message: 11/10/2006, 14h41
  5. Réponses: 4
    Dernier message: 26/09/2005, 22h36

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