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 :

Listes itératives, relatives, recursives et Makefile en C


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de mathieumadrid
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 39
    Par défaut Listes itératives, relatives, recursives et Makefile en C
    Bonjour,

    Je suis en train de faire des listes en C (listes itératives, relatives et récursives).
    J'ai fait les listes itératives et relatives. Ces listes sont composées d'éléments que l'utilisateur pourra insérer par la suite dans ses tests. Moi, je définis un élément comme ceci:

    Dans mes fichiers de test, je fais par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ELEMENT e1 = "1";
    insererFin(liste,&e1);
    ... et ça marche.
    Malgré tout, je ne pense pas que l'utilisateur puisse changer le type de l'élément. Par exemple, si on veut mettre des entiers ou des floats dans la liste; comment faire ?

    Cependant, on nous impose de faire comme ceci (c'est un devoir d'école):

    Il faut également faire des casts (char*) dans les fonctions qui utilisent ELEMENT*. Est-ce qu'avec cette méthode, on pourra insérer des éléments de n'importe quel type dans les listes ? Si oui, comment faire dans les fichiers de test ? et dans les fichiers sources (car je crois que ça change 2 ou 3 trucs) ?

    Sinon, pour tester mes listes, j'ai fait un Makefile. Celui-ci marche mais il a un comportement très bizarre. C'est à dire que je suis obligé de mettre -rm -f *.o pour qu'il puisse refaire les objets ensuite ! Il m'indique des alertes très louches. Y a-t-il un problème dans le Makefile (j'ai un autre Makefile qui s'occupe des sources et des librairies et il marche parfaitement).

    Enfin, j'ai des fonctions detruire dans iterative.c et relative.c qui doivent faire le ménage (free). Celle de iterative.c me semble correcte (je ne suis pas sûre) mais celle de relative.c me pose des problèmes. Comment éliminer les cellules d'une liste relative doublement chaînée ?

    Voilà, je vous laisse mon projet si vous voulez le voir ou le tester...

    merci
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mathieumadrid
    Ces listes sont composées d'éléments que l'utilisateur pourra insérer par la suite dans ses tests. Moi, je définis un élément comme ceci:
    Dans mes fichiers de test, je fais par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ELEMENT e1 = "1";
    insererFin(liste,&e1);
    ... et ça marche.
    OK.
    Malgré tout, je ne pense pas que l'utilisateur puisse changer le type de l'élément. Par exemple, si on veut mettre des entiers ou des floats dans la liste; comment faire ?
    un char * peut stocker l'adresse d'un objet d'un autre type. C'est un peut goret, mais ça marche. Il faut jouer des cast. Attention, la donnée dont on met l'adresse dans le pointeur doit être persistante (statique ou allouée).

    Ce serait plus propre si le type était void *.

    mais dans tous les cas, je n'aime pas qu'on cache le fait qu'on a affaire à un pointeur. (même pas de 'P' dans l'identificateur)...

    Cependant, on nous impose de faire comme ceci (c'est un devoir d'école):

    T'est sûr ? Si oui, change d'école. Et vite. Un pointeur n'est pas compatible avec un char.

  3. #3
    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 : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Délosé, mais je n'arrive pas à télécharger ton fichier rar... donc je travaille un peu à l'aveuglette...

    Dés qu'on parle de liste, j'ai tendance à penser "structure de liste (simplement ou doublement, selon le cas) chainée"...

    Est-ce de cela qu'il s'agit

    Si oui, la structure idéale se fait sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /*pour trouver ton ELEMENT*/
    typedef char ELEMENT; /*si tu veux un int, il suffit de char en int ;)*/
    /*La structure en elle meme */
    typedef struct SListe
    {
        ELEMENT elem;
        struct SListe *Suivant;
        /* éventuellement, si on parle d'une liste doublement chainée
         *   (qu'on doit parcourrir dans les deux sens)
         * struct SListe*Precedent;
         */
    }Liste;
    Avec ca, tu as la base pour travailler... Soit en "statique", soit en dynamique (ce qui est peut etre préférable)

    En statique, cela fonctionnerait sous la forme de
    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
     
    int main(int argc, char *argv[])
    {
        Liste F1={'b',NULL};
        Liste F2={'o',NULL};
        Liste F3={'n',NULL};
        Liste F4={'j',NULL};
        Liste F5={'o',NULL};
        Liste F6={'u',NULL};
        Liste F7={'r',NULL};
        Liste *temp=NULL;
        F1.Suivant=&F2;
        F2.Suivant=&F3;
        F3.Suivant=&F4;
        F4.Suivant=&F5;
        F5.Suivant=&F6;
        F6.Suivant=&F7;
        temp=&F1;
        while(temp!=NULL)
        {
             printf("%c",temp->elem);
             temp=temp->Suivant;
        }
        return 0;
    }
    En gestion dynamique, cela pourrait prendre la forme de (c'est un exemple, d'autres solutions sont envisageables
    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
    49
    50
    51
    52
    53
    54
     
    Liste* Ajout(Liste *actuel, ELEMENT val);
    /*une fonction pour la libération (également récursive)
       @arg élément de la liste */
    void Liberer(Liste *actuel);
    /*La fonction principale */
    int main(int argc, char *argv[])
    {
        Liste *PTemp=NULL;
        Liste *PFinal=Ajout(NULL,'b');
        Ajout(PFinal,'o');
        Ajout(PFinal,'n');
        Ajout(PFinal,'j');
        Ajout(PFinal,'o');
        Ajout(PFinal,'u');
        Ajout(PFinal,'r');
        PTemp=PFinal;
        while(PTemp!=NULL)
        {
             printf("%c",PTemp->elem);
             PTemp=PTemp->Suivant;
        }
        Liberer(PFinal);
        PFinal=NULL;
    }
    Liste * Ajout(Liste *actuel,ELEMENT val)
    {
        Liste *nouveau;
        if(actuel==NULL)
        {
            nouveau=malloc(sizeof(Liste));
            if(nouveau!=NULL)
            {
                nouveau->Suivant=NULL;
                nouveau->elem=val;
            }
        }
        else
        {
            actuel->Suivant=Ajout(actuel->Suivant,val);
            return nouveau=actuel;
        }
            return nouveau;
    }
    void Liberer(Liste* actuel)
    {
        if(actuel->Suivant!=NULL)
        {
            Liberer(actuel->Suivant);
        }
        /* la ligne suivante est plus là par habitude qu'autre chose ;) */
        actuel->Suivant=NULL;
        free(actuel);
    }
    Evidemment, les boucles d'affichages ne sont là que pour montrer le résultat...

    Elle devront en tout état de cause etre modifiée en fonction du type aliasé par ELEMENT
    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

Discussions similaires

  1. Création d'une liste de manière itérative
    Par nahlette dans le forum Prolog
    Réponses: 2
    Dernier message: 29/11/2007, 11h18
  2. Makefile / Liste des dépendances
    Par Gigo dans le forum Systèmes de compilation
    Réponses: 6
    Dernier message: 06/08/2007, 20h44
  3. Liste itérative ou récursive
    Par devstud dans le forum C
    Réponses: 11
    Dernier message: 04/01/2007, 17h07
  4. Liste itérative en C
    Par mathieumadrid dans le forum C
    Réponses: 22
    Dernier message: 28/11/2006, 04h56
  5. Liste recursive de repertoire AVEC filtre
    Par skunkies dans le forum Langage
    Réponses: 3
    Dernier message: 24/11/2006, 08h59

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