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 :

liste chainée & structure


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Points : 46
    Points
    46
    Par défaut liste chainée & structure
    salut j'ai creer une structure et une liste chainée , mon but est de mettre le contenu de la variable prd dans chaine mais le compilo refuse de l'accepter!

    type_produit et
    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
    #include <stdio.h>
    #include <stdlib.h>
    typedef struct type_produit
    {
    	char code[4];//ou 3 a verfier
    	char design[30];
    	char prix[10];
    	char stock[5];
    	char code_famille[5];
    	char code_fournisseur[5];
    }produit;
    typedef struct type_cellule_produit
    {
    	produit data;
    	struct type_cellule_produit *suiv;
    }cellule_produit;
     
     
    int main()
    {
    produit prd;
    cellule_produit *chaine;
    prd.code="1234";//initialisation j'ai choisis code pour faire court 
    chaine->data.code=prd.code;//affectation mais ça plante !
     
    return 0;
    }
    svp est ce que vous pouvez m'indiquer le probleme et me corriger mon code ?
    merci bcp

  2. #2
    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 hunter99
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    cellule_produit *chaine;
    chaine->data.code=prd.code;//affectation mais ça plante !
    chaine est un pointeur non initialisé. Tu espères quoi au juste ?
    De plus, pour copier une chaine, c'est strcpy() ou un de ses frères...

    Le C, ça ne s'improvise pas. Ca s'apprend...

    Tu fais quoi pour ça ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 689
    Points
    30 689
    Par défaut
    Salut,

    Si tu peux envisager de travailler avec une liste simplement chainée de manière statique, il faut savoir que... ce n'est vraiment pas efficace (comme d'autres concepts, par définition, une liste est une structure dynamique, et il est donc préférable de la gérer... de manière dynamique )

    En plus, qui dit "liste" (comme les autres structures dynamiques) dit généralement "plus d'un élément"... sinon, il n'y a pas d'intéret à s' avec

    Donc, comme tu as pris un exemple statique, et bien que ce ne soit pas recommandé, on va te donner un exemple statique concret (c'est à dire, avec deux élément... Ben oui, c'est plus d'un, et j'ai la flegme ), avec les commentaires qui vont bien... les structures restent les meme que celles que tu nous présentes
    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
     
    int main(int argc, char *argv[])
    {
        /*on va déclarer deux produits... */
        type_cellule_produit produit1;
        type_cellule_produit produit2;
        /* et un pointeur pour suivre la liste */
        type_cellule_produit* liste;
        /*on initialise produit1 */
        strcpy(produit1.data.code,"123");/* avec code[4], il faut penser qu'on n'a
                                          * que trois caracteres utiles 
                                          * (il faut le \0 final) */
        strcpy(produit1.data.prix,"156,48");/* Typiquement, un prix serait bien 
                                             * mieux avec une valeur
                                             * numérique... tu risque  
                                             * de vouloir effectuer des 
                                             * opérations mathématiques dessus ;) */
        /* bon, on n'oublie pas les autres valeurs de data ;) */
        /* et on fait pareil avec produit2 */
        /* (...) */
        /* il reste à faire pointer produit1.suiv sur "l'adresse de produit2" c'est ca
         * un pointeur ;) */
        produit1.suiv=&produit2;
        /* et, pour éviter les problèmes, à faire pointer produit2.suiv sur ...NULL */
        produit2.suiv=NULL;
        /* Sans oublier de faire pointer notre "pointeur de liste" sur le début de la 
         * liste (AKA: l'adresse de produit1 ;) ) */
        liste=&produit1;
        /* on peut maintenant utiliser la liste (par exemple pour un affichage) */
        while(liste!=NULL)
        {
            /*(...)tout l'affichage, que je te laisse gérer */
            /* et on passe à l'élément suivant de la liste */
            liste=liste->suiv;
            /* NOTA: ici, comme les éléments de la listes sont déclarés de 
             * statiquement, ca ne fait rien si on perd le premier élément...
             * Avec une allocation dynamique, il est primordial de veiller à ne 
             * JAMAIS perdre le premier élément;) */
        }
        /* il n'y a pas eu d'allocation dynamique, on peut quitter */
        return 0;
    }
    Maintenant, il n'y a aucun intéret à utiliser une liste de manière statique... et encore moins quand les éléments sont écrits "en dur" dans le code source...

    L'utilisation des tableaux présenterait une alternative des plus valable pour l'exemple que je viens de te donner

    Par contre, les listes deviendront intéressantes dés le moment où il s'agira de demander à l'utilisateur d'introduire les différents articles et/ou de lire une liste "préexistante" dans un fichier...

    L'astuce, c'est que, comme l'utilisateur peut se lasser d'encoder les articles apres le 10eme... ou apres le 10.000eme... (ou peut etre y a-t-il 100.000 article sans un fichier ) il s'agira de travailler de manière dynamique...

    Je ne vais donner qu'un morceau d'exemple, mais cela te permettra de comprendre
    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
    int main(int argc, char* argv[])
    {
        /* il nous faut trois pointeur pour travailler à notre aise:
         * -celui en début de liste (à ne surtout pas perdre)
         * -celui en fin de liste (à garder tout aussi précieusement)
         * -un pointeur de travail 
         */
         type_cellule_produit *Debut=NULL;
        type_cellule_produit *Fin=NULL;
        type_cellule_produit *tempo=NULL;
    /* NOTA: La meilleure habitude à prendre, lorsque l'on travaille avec des
     * pointeurs, est de TOUJOURS les initialiser à NULL tant qu'on ne dispose
     * pas d'une valeur à leur donner et de TOUJOURS tester qu'ils soient
     * bien différents de NULL avant d'essayer de les utiliser */
        /* le tout se fera dans une boucle, agrémentée d'un choix...
         * à effectuer jusqu'à ce que l'utilisateur veuille arreter */
        do
        {
            /* affichage du menu, et selection de l'utilisateur que je te laisse
             * implémenter */   
            if(choix==1) /*l'utilisateur a choisi de continuer */
            {
                /* on va appeler une fonction qui se chargera d'allouer et
                 * d'initialiser correctement le nouvel élément...
                 * elle renverra NULL en cas d'échec, et un pointeur sur l'élément
                 * créé en cas de réussite... on le récupere dans tempo */
                tempo=cree_article();
                /* on teste que ca aie fonctionné */
                if(tempo!=NULL)
                {
                    /* C'est peut etre le premier élément de la liste */
                    if(Debut==NULL)
                        Debut=tempo /* si c'est le cas, le nouvel élément devient
                                     * le début */
                    /* et, si il y a déjà des éléments */
                    if(Fin!=NULL)
                        Fin->suiv=tempo; /* on rajoute tempo apres le dernier */
                    Fin=tempo; /* quoi qu'il en soit, le nouvel élément devient
                                * la fin de la liste */
                }
                  
            }while(choix==0);/*l'utilisateur a choisi de quitter le programme */
        /*Appel d'une fonction de libération */
        Libere(Debut);
        /* on peut quitter sans risque */
        return 0;
    }
    Evidemment, il y a deux fonctions qui viennent compléter le code:
    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
     
    /* fonction qui crée un nouvel article
     * @ in rien
     * @ out: pointeur sur l'élément créé et initialisé
     */
    type_cellule_produit* cree_article()
    {
        /*il nous faut un pointeur sur le nouvel élément */
        type_cellule_produit *nouveau;
        /* il faut l'allouer dynamiquement (malloc renvoie null en cas d'échec)
         * et il faut TOUJOURS en tester le résultat */
        if((nouveau=malloc(sizeof(type_cellule_produit))!=NULL)
        {
             /*l'allocation a réussi... la première chose à faire, c'est de mettre
             *nouveau->suiv à NULL */
            nouveau->suiv=NULL;
            /* il ne reste plus qu'à demander à l'utilisateur d'introduire les 
             * informations sur l'élément créé je t'en laisse le soin ;)*/
        }
        /* on renvoie le résultat */
        return nouveau;
    }
    /* Fonction qui va libérer proprement l'ensemble de la mémoire allouée
     * de manière dynamique 
     * @ in: le pointeur sur le début de la chaine 
     * @ out: rien 
     */
    void Libere(type_cellule_produit *debut)
    {
        /* il nous faut un pointeur de travail */
        type_cellule_produit *travail=NULL;
        /* une boucle à effectuer tant qu'il y a un élément dans la liste */
        while(debut!=NULL)
        {
            /*Si on libère debut avant d'avoir récupéré l'élément suivant, on est
             * marron... donc, on récupère debut->suiv dans travail */
            travail=debut->suiv;
            /* on peut liberer debut sans problème */
            free(debut);
            /* l'élément qui suivait debut devient le nouveau début */
            debut=travail;
        }
        /*C'est fini */
    }
    NOTA: Bien que le code lui-même revete une certaine importance, c'est surtout les commentaires que j'ai placés dedans (et qui font la majeure partie, d'ailleurs ) qui te permettront de comprendre ce qui est fait, quand et pourquoi

  4. #4
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Points : 46
    Points
    46
    Par défaut
    merci bcp .J'ai une autre question , tu dis que
    strcpy(produit1.data.code,"123");/* avec code[4], il faut penser qu'on n'a
    * que trois caracteres utiles
    .
    alors que si on declaré une chaine de cractere chaine[4] on disposait de 4 caractere et le 5eme contenait '\0' .C'est faux ce que je dis ?

  5. #5
    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 hunter99
    merci bcp .J'ai une autre question , tu dis que .
    alors que si on declaré une chaine de cractere chaine[4] on disposait de 4 caractere et le 5eme contenait '\0' .C'est faux ce que je dis ?
    Désolé d'insister, mais la on est dans la base du C. Alors je t'invite à suivre un cours de C sérieux (tutoriel, livre, des références sur mon site), et à cesser de poser des questions basiques.

    Il est hors de question que tu abordes un sujet aussi complexe que les listes chainées si tu ne maitrises pas les bases du C.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 689
    Points
    30 689
    Par défaut
    Citation Envoyé par hunter99
    merci bcp .J'ai une autre question , tu dis que .
    alors que si on declaré une chaine de cractere chaine[4] on disposait de 4 caractere et le 5eme contenait '\0' .C'est faux ce que je dis ?
    Quand tu déclares un tableau
    le langage fait ce que tu lui demande: il alloue la mémoire pour quatre éléments (ici, tab[0], tab[1], tab[2] et tab[3])... Il n'a aucune raison de t'allouer de la mémoire pour plus que ce que tu lui demandes

    Donc, étant donné qu'une chaine en C doit etre terminée par un caractère nul ('\0'), si tu veux quatre caractères utiles, il te faut... 5 places...

    Et, pour les avoir, tu dois déclarer ton tableau en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char tabcar[5];
    /*   OU --- OU--- OU--- */
    /* pour te rappeler qu'il y a le '\0' en plus */
    char tabcar[4+1];
    /*ce qui revient au meme */
    Ceci dit, je rejoins tout à fait l'opinion d'Emmanuel, avant de t'attaquer à des choses aussi complexes que les structures dynamiques (car il n'y a pas que les listes), il serait intéressant que tu comprennes correctement les bases...

  7. #7
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Points : 46
    Points
    46
    Par défaut
    don si je veut utiliser une chaine avec 5 caractere je dois declaré une char chaine [6] c'est bien ça ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 689
    Points
    30 689
    Par défaut
    Citation Envoyé par hunter99
    don si je veut utiliser une chaine avec 5 caractere je dois declaré une char chaine [6] c'est bien ça ?
    heu... vu que 5+1 font 6... ca semble logique, oui...

  9. #9
    Membre du Club
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Points : 46
    Points
    46
    Par défaut

Discussions similaires

  1. liste chainée sur structure
    Par mondanikoffi dans le forum C++
    Réponses: 8
    Dernier message: 28/10/2013, 04h05
  2. liste chainé et structure
    Par TII18 dans le forum C
    Réponses: 3
    Dernier message: 30/12/2010, 13h53
  3. Liste chaine et structure dans structure
    Par firemax dans le forum C
    Réponses: 1
    Dernier message: 04/12/2007, 18h06
  4. les listes chaineés(structures)
    Par snakemetalgear dans le forum C
    Réponses: 18
    Dernier message: 14/11/2006, 18h09
  5. [Débutant]Structure et listes chainées
    Par plagia dans le forum C
    Réponses: 28
    Dernier message: 09/11/2006, 00h00

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