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 :

Fonction vider_liste_chainée generique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Par défaut Fonction vider_liste_chainée generique
    Slt ,comme je manipule plusieurs listes simplement chaînées qui ne sont pas du meme type (chqe liste contient une structure differente), je me suis demandé si c’est possible d’écrire une seule fonction vider_liste qui marche pour toutes les listes.Est ce que c’est fesable en C ?merci

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par hunter99
    .Est ce que c’est fesable en C ?merci

    oui et non...

    Tou dépend de ce que tu as dans les structures. Si il y a des allocations, ça risque d'être impossible.... Sinon oui ça se fait...

  3. #3
    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 hunter99
    Slt ,comme je manipule plusieurs listes simplement chaînées qui ne sont pas du meme type (chqe liste contient une structure differente), je me suis demandé si c’est possible d’écrire une seule fonction vider_liste qui marche pour toutes les listes.Est ce que c’est fesable en C ?merci
    Oui, bien sûr. Il suffit que les données soient gérées extérieurement. Le gestionnaire de listes se contente alors de gérer les liens, et d'appeler les callbacks nécessaires (free, par exemple, si l'objet à libéer est complexe).

    En interne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct node
    {
       /* liens */
       struct node *p_next;
     
       /* donnees generiques 
         (une adresse suffit, à l'application de se débrouiller) */
       void *p_data;
    };
    Les données doivent se résumer à une adresse (parfait pour les ADT). La signification est connue de l'application, mais le gestionnaire de listes génériques ne sait pas de quoi il s'agit. Pour libérer correctement, il faut faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /* list.h */
    typedef void list_free_f (void *p_data);
    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
     
    /* liste.c */
    ...
     
    void list_delete (noeud ** pn, list_free_f *pf)
    {
       noeud *n = *pn;
       while (n != NULL)
       {
          noeud *temp = n;
          n = n->svt;
          pf (temp); /* EDIT */
       }
       *pn = NULL;
    }
    dans l'application :
    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
     
    /* main.c */
    #incude "data.h" /* donnees */
     
    void free_data (void *p_data)
    {
       data_delete(p_data);
    }
     
    int main (void)
    {
       list *n = NULL;
       ...
       list_free (n, free_data);
       ...
    }
    ou
    dans les cas triviaux.

    C'est un projet intéressant qu'il faut réaliser avec la plus grande rigueur, comme d'habitude. L'avantage, c'est qu'ensuite, on a du code réutilisable...

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    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
     
    /* liste.c */
    ...
     
    void list_delete (noeud ** pn, liste_free_f *pf)
    {
       noeud *n = *pn;
       while (n != NULL)
       {
          noeud *temp = n;
          n = n->svt;
          fp (temp);
       }
       *pn = NULL;
    }
    Attention, petite faute de frappe pas bien méchante: fp à la place de pf (ou le contraire).

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  5. #5
    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 mujigka
    Attention, petite faute de frappe pas bien méchante: fp à la place de pf (ou le contraire).

    Thierry
    Corrigé, merci.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Oui, bien sûr. ...
    C'est un projet intéressant qu'il faut réaliser avec la plus grande rigueur, comme d'habitude. L'avantage, c'est qu'ensuite, on a du code réutilisable...
    Ah ok comme ça..... Oui...

    Mais au vu de la simplicité de libérer l'élément de la liste chaînée par rapport à la complexité (éventuelle) de libérer un élément du type inclus, je trouve que fonctionnellement c'est plus simple de faire libérer_liste_type1, libérer_liste_type_2, etc...
    D'autant plus que ça implique que toutes les listes soient conçues de la même manière (dans ton cas juste avec suivant). Donc si tu en construisais une avec précédent, faut refaire une routine, ou rajouter un paramètre en entrée et un if ou switch dedans, et si c'était dans les 2 sens aussi...

    Enfin, bon c'est mon point de vue.... Si on est sûr de toujours avoir des listes de la même conception, éventuellement...

  7. #7
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct node
    {
       /* liens */
       struct node *p_next;
     
       /* donnees generiques 
         (une adresse suffit, à l'application de se débrouiller) */
       void *p_data;
    };
    >Ça veut dire que la cellule est formé du pointeur sur la cellule suivante et d’un pointeur void vers les données ? on modifie la cellule elle-même pour quelle devienne une cellule générique ?
    Est-ce que void* est une sorte de pointeur caméléon ?
    qcq ça veut dire cette instruction ?

    >souviron34 c'est juste pour voir ce que ça peut m'apporter mais si ça devient trop compliqué je laisse tomber.

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par hunter99
    >Ça veut dire que la cellule est formé du pointeur sur la cellule suivante et d’un pointeur void vers les données ? on modifie la cellule elle-même pour quelle devienne une cellule générique ?
    Est-ce que void* est une sorte de pointeur caméléon ?
    Oui c'est bien ça.... tu l'utilises lorsque tu veux passer (ou appeler) avec le même paramètre (ou la même fonction) des choses différentes.

    Citation Envoyé par hunter99
    qcq ça veut dire cette instruction ?
    c'est la routine de libération du contenu de la structure, passée en paramètre, (elle s'appelle free_data, mais le paramètre s'appelle *fp). Et elle a en paramètre en void*, repésentant les données, enfin le contenu de la structure, et donc si il y a des chaînes allouées, des tableaux, etc, c'est là dedans que tu les libéreras.

  9. #9
    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 hunter99
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    struct node
    {
       /* liens */
       struct node *p_next;
     
       /* donnees generiques 
         (une adresse suffit, à l'application de se débrouiller) */
       void *p_data;
    };
    >Ça veut dire que la cellule est formé du pointeur sur la cellule suivante et d’un pointeur void vers les données ? on modifie la cellule elle-même pour quelle devienne une cellule générique ?
    On ne modifie rien du tout. Le noeud générique est ceci. Simplement, les données sont ailleurs. On ne connait que leur adresse. Ni leur structure ni leur sémantique.
    Est-ce que void* est une sorte de pointeur caméléon ?
    Pas 'camé, léon', mais simplement 'anonyme'. On a juste besoin de se souvenir de l'adresse du bloc de données. Celui-ci est géré par l'application (TAD recommandé).
    qcq ça veut dire cette instruction ?
    Faute de frappe. C'est pf (le pointeur de fonction passé en paramètre).

  10. #10
    Membre confirmé
    Inscrit en
    Décembre 2006
    Messages
    112
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 112
    Par défaut
    TAD recommandé
    TAD qu'est ce que ça veut dire ?

Discussions similaires

  1. [Generics] Surcharges de fonctions avec generiques
    Par zax-tfh dans le forum Framework .NET
    Réponses: 3
    Dernier message: 03/07/2013, 11h12
  2. Creer une fonction generique
    Par chris81 dans le forum Windows Presentation Foundation
    Réponses: 9
    Dernier message: 24/12/2008, 15h13
  3. Fonction de traitement sur tables generiques
    Par Clorish dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 03/12/2007, 23h26
  4. Implementer une fonction generique
    Par Seth77 dans le forum C#
    Réponses: 7
    Dernier message: 26/02/2007, 11h11
  5. Appel generique de pointeur de fonction qui...
    Par MonsieurAk dans le forum C
    Réponses: 7
    Dernier message: 07/03/2006, 22h05

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