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 :

Demande explication Liste chaînée


Sujet :

C

  1. #1
    Candidat au Club
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Demande explication Liste chaînée
    Bonjour tout le monde,

    je suis étudiante en deuxième IUT et je suis face à un petit problème concernant un exercice sous C sur les listes chaînées.

    Première question: Pourriez-vous SVP m'expliquer et analyser ce bout de code (je sais qu'il s'agit d'une déclaration de liste chainée (_host & maillon_reseau) avec des champs nom et address .... mais y'a des champs par exemple que je comprenne pas : host pHost | maillon_reseau *m_reseau ...etc).

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct _host
    {
        char nom [50];
        char address [4];
     
    } host;
     
    typedef struct _maillon_reseau
    {
        host mHost ;
        struct _maillon_reseau *suivant ;
        struct _maillon_reseau *precedent ;
     
    } maillon_reseau ;
     
    int main (int argc, char **argv)
    {
        host pHost ;
        char address [4] ="127.0.0.1";
        maillon_reseau *m_reseau;
    }
    Deuxième question : remplissez le tableau suivant (j'ai pas très compris quoi mettre dans les champs à coté de chaque type d'entité ... :$):

    sachez que sur l'exo, c'est marqué comme quoi il y'a des champs incorrecte et donc il faut mettre tout simplement un X à coté.

    • pHost
    • (*pHost).nom
    • pHost-> message [0]
    • M_reseau.suivant.com
    • M_reseau->suivant->nom
    • Adresse [0]
    • Argv
    • Argv[0]


    Je vous remercie tout ceux qui peuveut m'aider à résoudre et comprendre cet exercice.

    Jiji.

  2. #2
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Désolé si c'est trop direct mais: Tu connais les pointeurs?

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    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 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Bonjour et bienvenue,

    Citation Envoyé par JijiRajoua Voir le message
    Première question: Pourriez-vous SVP m'expliquer et analyser ce bout de code
    On peut t'aider, mais on ne fera pas ton travail à ta place. Montre-nous ce que tu as réalisé et dis-nous sur quels points tu bloques en particulier.

    (je sais qu'il s'agit d'une déclaration de liste chainée (_host & maillon_reseau) avec des champs nom et address .... mais y'a des champs par exemple que je comprenne pas : host pHost | maillon_reseau *m_reseau ...etc).
    La ligne « char addresse[4] » entre autres est totalement incorrecte.

    « host » est un nom de type que tu as déclaré en tête de programme et qui équivaut à la structure « struct _host », qui elle-même sert à représenter un nom de machine (ou hôte, d'où host), en embarquant son nom et son adresse réseau.

    « pHost » est le nom que tu donnes à un instance de cette structure, et « maillon_reseau * » est un pointeur, contenu de ta structure « maillon_reseau », et qui pointe vers une autre structure maillon_reseau, de façon à pouvoir former une chaîne.

  4. #4
    Candidat au Club
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2013
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    oui je connais

    pointeurs "suivant" vers structure suivante "liste chainée simple"
    pointeurs "suivant et précédent" vers structure suivante et précédente "liste chainée double".

    pointeurs servent à faire pointer le maillon vers une structrure (liste chainée suivante ou précedente). c ca ?

    pourriez vous me donner une explication du code svp et le tableau ?

    merci bcp

  5. #5
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Citation Envoyé par JijiRajoua Voir le message
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct _host
    {
        char nom [50];
        char address [4];
     
    } host;
     
    typedef struct _maillon_reseau
    {
        host mHost ;
        struct _maillon_reseau *suivant ;
        struct _maillon_reseau *precedent ;
     
    } maillon_reseau ;
     
    int main (int argc, char **argv)
    {
        host pHost ;
        char address [4] ="127.0.0.1";
        maillon_reseau *m_reseau;
    }
    struct "nom" : te permet de definir un nouveau type de variables en gros.
    Cela te permet de stocker des variables de type plus communs comme les int, double etc...
    Par exemple "struct _host" est maintenant un nouveau type de variable que tu vas pouvoir créer.
    Désormais au lieu d’écrire "int a = 0;" tu pourras mettre "struct _host test = ...;"

    typedef struct "nom1" {...} "nom2" : te permet de modifier le nom struct machin en un autre nom.
    Le paragraphe ci dessus j'ai mis struct _host test;
    Avec ton typedef défini tel que: typedef struct _host host;
    Tu peux créer dorénavant des variables telles que: host test = ...;

    Voila pour la première structure.

    Pour la deuxième c'est exactement la même chose.
    Sauf qu'elle, elle contient des pointeurs (tu les reconnais grâce aux * devant leurs noms).
    Cependant, petit bémol à ton titre, il s'agit ici d'une liste doublement chainée car tu as un pointeur sur l’élément suivant et un pointeur sur l’élément précédent.

    Finalement dans le main, tu vas creer 3 variables.

    La premiere est "host pHost;". Il s'agit d'un type que tu as créé au dessus mais le nom de ta variable est quelque peu farfelu comparé à comment elle s'appelle (pnom est en général, pour moi, un pointeur sur la variable nom).
    Ensuite char adresse euh... pourquoi 4 cases? Tu veux rentrer quoi dedans?
    Et ensuite "maillon_reseau *m_reseau;" il s'agit juste d'un pointeur sur une variable de type maillon_reseau définie au début

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bysbobo Voir le message
    Ensuite char adresse euh... pourquoi 4 cases? Tu veux rentrer quoi dedans?
    Salut

    Ben c'est pour y stocker l'adresse IP !!! Une case par valeur...

    Ensuite, en ip v6, suffira de rajouter une autre variable...

    Citation Envoyé par JijiRajoua Voir le message
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct _host
    {
        char nom [50];
        char address [4];
     
    } host;
     
    typedef struct _maillon_reseau
    {
        host mHost ;
        struct _maillon_reseau *suivant ;
        struct _maillon_reseau *precedent ;
     
    } maillon_reseau ;
     
    int main (int argc, char **argv)
    {
        host pHost ;
        char address [4] ="127.0.0.1";
        maillon_reseau *m_reseau;
    }
    Je ne sais pas si ce code est de toi ou s'il est dans l'énoncé mais tu remarqueras déjà que la façon de nommer les éléments est préjudiciable. Par exemple tu ne peux pas avoir de variable "host" puisque ce token est utilisé pour un type.
    Donc si c'est de toi, alors tu devrais de suite prendre la bonne habitude de nommer tes structures "s_qqchose" et tes types "t_qqchose". Ca te laissera alors le choix d'utiliser "qqchose" pour tes variables.

    Ensuite, quand on manipule une liste, une autre bonne idée est de penser aussi à créer une structure dédiée à la liste elle-même. Et ce pour 2 raisons
    1. si jamais tu veux rajouter un élément associé à ta liste (par exemple le nombre de maillons, ou le dernier maillon, ou autre), te suffit de le rajouter dans la structure. Toutes les fonctions recevant la liste auront de facto accès à cet élément.
    2. si jamais ta liste doit être modifiée, la fonction modifiant la liste recevra un pointeur simple (une étoile) sur la structure. De là elle aura facilement accès aux éléments. Alors que dans ton cas, si jamais tu écris une fonction devant modifier "m_reseau" (qui est déjà un pointeur), alors ta fonction devra recevoir l'adresse de ce pointeur qu'elle devra stocker dans un étoile étoile. Et elle devra tout le long de son travail, manipuler (*x). Bon ça se fait bien sûr mais c'est un peu lourd.


    Donc je te propose les structures suivantes

    Code c : 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
    typedef struct { // Pas besoin de nom ici puisque la structure devient immédiatement un type
        char nom [50];
        char address [4];
    } t_host;
     
    typedef struct s_maillon { // Ici il faut un nom car la structure doit se connaitre pour pouvoir créer des pointeurs dessus
        t_host host ;
        struct s_maillon *suivant ;
        struct _maillon *precedent ;
    } t_maillon;
     
    typedef struct {
        t_maillon *debut;
        t_maillon *fin;
        int nb_maillon;
    } t_liste;

    Tu verras que la manipulation est ensuite facilitée. Par exemple

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void initListe(t_liste *p)
    {
        p->debut=NULL;
        p->fin=NULL;
        p->nb_maillon=0;
    }
     
    int main()
    {
        t_liste liste;
        initListe(&liste);
    }

    Je pense même qu'en comparant mon exemple et ton énoncé, tu devrais arriver à voir à quoi correspond tel ou tel item dans ton énoncé.

    Pour le reste, par exemple char address [4] ="127.0.0.1" je pense que si t'en es aux listes chainées et aux pointeurs tu connais alors déjà la syntaxe de base sur les éléments simples (du moins tu es sensé la connaitre) pour voir ce qui cloche ici...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Citation:
    Envoyé par Bysbobo Voir le message
    Ensuite char adresse euh... pourquoi 4 cases? Tu veux rentrer quoi dedans?
    Salut

    Ben c'est pour y stocker l'adresse IP !!! Une case par valeur...
    En fait, ce n'est l'utilisation qui me choque, c'est l'implémentation. Si tu veux y stocker ton adresse IP, pourquoi pas passer par un "int IP[4];" ?
    Parce que la je ne suis pas sur du résultat...

  8. #8
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Citation Envoyé par Bysbobo
    En fait, ce n'est l'utilisation qui me choque, c'est l'implémentation. Si tu veux y stocker ton adresse IP, pourquoi pas passer par un "int IP[4];" ?
    Parce que la je ne suis pas sur du résultat...
    Ou tout simplement par un int. Après tout, un char[4] c'est 4 octets, tout comme un int. Pourquoi s'embêter avec un tableau dans ce cas-là ?

  9. #9
    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
    Peut-être parce qu'avec un int, on va probablement avoir besoin de jouer avec les opérateurs binaires?

    Concernant les nommages, on peut aussi adopter la convention C: "machin_t", tel time_t, char_t ou uint8_t
    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

  10. #10
    Membre averti
    Homme Profil pro
    Cadre informatique
    Inscrit en
    Avril 2013
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Cadre informatique

    Informations forums :
    Inscription : Avril 2013
    Messages : 183
    Points : 435
    Points
    435
    Par défaut
    Je suis d'accord mais la façon dont c'est initialisé ne pose pas un problème?
    "128.0.0.1" sera considéré comme une suite de caractère avec les " " non?
    Donc 4 cases ne seront pas suffisant dans ce cas?
    Et si jamais on passe par un int, on fait ça comment?

  11. #11
    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
    C'est {128,0,0,1} qui serait un bon initialiseur.

    Cela dit, personnellement, j'opterai pour un unsigned char ip[4];Pour l'entier, ca serait proche de unsigned int ip = (128u<<24)|(0u<<16)|(0u<<8)|(1u); ou en plus direct unsigned int ip = (128u<<24)|1u;
    Dans ce contexte, je te recommande de passer par une fonction, pour écrire unsigned int ip = ip(128,0,0,1);:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned int ip(unsigned char a, unsigned char b, unsigned char c, unsigned char d) {
        return (a<<24)|(b<<16)|(c<<8)|d;
    }
    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

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bysbobo Voir le message
    En fait, ce n'est l'utilisation qui me choque, c'est l'implémentation. Si tu veux y stocker ton adresse IP, pourquoi pas passer par un "int IP[4];" ?
    Parce que le char est aussi un nombre et qu'en dehors de sa plage de valeurs, il se comporte exactement comme un int...
    Citation Envoyé par Bysbobo Voir le message
    Parce que la je ne suis pas sur du résultat...
    Effectivement il vaut mieux mettre du unsigned char mais même en signed char, ça peut marcher (car 255 ou -1 se codent tous les deux 0xff). C'est lors des calculs éventuels que ça peut faire une différence.
    Ceci dit, moi je préfère évidemment mettre du unsigned...

    Citation Envoyé par leternel Voir le message
    Concernant les nommages, on peut aussi adopter la convention C: "machin_t", tel time_t, char_t ou uint8_t
    Euh, une fois j'ai dit comme toi et je me suis fait ouvrir par Emmanuel Delahaye. Les token se terminant par "_t" sont réservés à Unix...

    Citation Envoyé par Bysbobo Voir le message
    Je suis d'accord mais la façon dont c'est initialisé ne pose pas un problème?
    "128.0.0.1" sera considéré comme une suite de caractère avec les " " non?
    Donc 4 cases ne seront pas suffisant dans ce cas?
    Arf fallait pas le dire !!! C'était une des questions de l'énoncé...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. explication sur cet algo de liste chaînée
    Par keokaz dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 26/03/2012, 11h21
  2. [AWT] Demande Explications prog calculatrice
    Par smag dans le forum Débuter
    Réponses: 3
    Dernier message: 07/07/2005, 16h06
  3. Listes chaînées circulaires
    Par gege2061 dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 11/05/2005, 13h44
  4. Construction de liste chaînées
    Par fomblardo dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 15/03/2005, 21h19
  5. Insertion d'un noeud dans une liste chaînée
    Par habib106 dans le forum Assembleur
    Réponses: 8
    Dernier message: 07/04/2004, 22h34

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