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 :

Pointeur de fonction


Sujet :

C

  1. #1
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut Pointeur de fonction
    Je m'attaque à la compréhension d'un concept très peu utilisé en langage C mais j'aimerais comprendre quand meme donc si il y a des gens qui capte ce concept
    Je vous lache un bout de code comme exemple
    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
     
    /**************************************************************
    *                                                                                                                        *
    *  ------------------------- list.h ------------------------  *
    *                                                                                                                        *
    **************************************************************/
     
    #ifndef LIST_H
    #define LIST_H
     
    #include <stdlib.h>
     
    /***************************************************************
    *                                                                                                                         *
    *  Définition de la structure pour les éléments de la liste  *
    *                                                                                                                         *
    ***************************************************************/
     
    typedef struct ListElmt_ {
     
    void			   *donnee;
    struct ListElmt_   *suivant;
     
    } ListElmt;
     
    /****************************************************************
    *                                                                                                                          *
    *  Définition d'une structure pour les listes chaînées                 *
    *                                                                                                                          *
    ****************************************************************/
     
    typedef struct List_ {
     
    int				taille;
     
    int				(*corresp)(const void *val1, 
    							  const void *val2);
    void			   (*detruire)(void *donnee);
     
    ListElmt		   *tete;
    ListElmt		   *queue;
     
    } List;
     
    /***************************************************************
    *                                                                                                                         *
    *  ----------------- Interface publique ---------------------  *
    *                                                                                                                         *
    ***************************************************************/
     
    void list_init(List *liste, void (*detruire)(void *donnee));
     
    void list_destroy(List *liste);
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    /************************************************************
    *                                                                                                                  *
    *  ------------------------ list.c -----------------------  *
    *                                                                                                                  *
    ************************************************************/
     
    #include <stdlib.h>
    #include <string.h>
     
    #include "list.h"
     
    /***********************************************************
    *                                                                                                                 *
    *  ---------------------- list_init ---------------------  *
    *                                                                                                                 *
    ***********************************************************/
     
    void list_init(List *liste, 
    			   void (*detruire)(void *donnee)) {
     
    /************************************************************
    *                                                                                                                  *
    *  Initialisation de la liste.                                                    *
    *                                                                                                                  *
    ************************************************************/
     
    liste->taille   = 0;
    liste->detruire = detruire;
    liste->tete	 = NULL;
    liste->queue	= NULL;
     
    return;
     
    }
     
    /*************************************************************
    *                                                                                                                       *
    *  ---------------------- list_destroy --------------------  *
    *                                                                                                                       *
    *************************************************************/
     
    void list_destroy(List *liste) {
     
    void			   *donnee;
     
    /*************************************************************
    *                                                                                                                       *
    *  Suppression de chaque élément.                                                     *
    *                                                                                                                       *
    *************************************************************/
     
    while (list_size(liste) > 0) {
     
       if (list_rem_next(liste, NULL, (void **)&donnee) == 0 && 
    	   liste->detruire !=  NULL) {
     
    	  /*****************************************************
              *                                                                                                     *
              *  Appel d'une fonction utilisateur pour libérer      *
              *  les données allouées dynamiquement.                         *
              *                                                                                                     *
              *****************************************************/
     
    	  liste->detruire(donnee);
     
       }
     
    }
     
    /************************************************************
    *                                                                                                                  *
    *  Aucune opération n'est encore permise, mais on nettoie   *
    *  la structure par précaution.                                                         *
    *                                                                                                                  *
    ************************************************************/
     
    memset(liste, 0, sizeof(List));
     
    return;
     
    }
    Alors mon truc c'est que je sais pas du tout comment dans mon main je vais pouvoir utiliser les structures et les fonctions que j'ai mise (init et destroy) à cause de ces pointeurs de fonction.

    Donc si quelqu'un y arrive ca m'interesse
    Merci d'avance.

  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 AuraHxC
    Je m'attaque à la compréhension d'un concept très peu utilisé en langage C
    Tu parles de pointeurs de fonctions ? C'est une plaisanterie ? Les interpréteurs de commandes, les automates (FSM) et toute la programmation par évènement (GUI, par exemple) est basée sur l'utilisation des pointeurs de fonctions. C'est aussi le seul moyen de réaliser des composants logiciels indépendant des sorties.

    http://emmanuel-delahaye.developpez.com/complog.htm

    C'est certes un concept 'avancé' du langage (encore qu'il n'est pas propre à celui-ci), mais peu connu, non (à part des débutants, bien sûr).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    typedef struct List_ {
     
    int				taille;
     
    int				(*corresp)(const void *val1, 
    							  const void *val2);
    void			   (*detruire)(void *donnee);
     
    ListElmt		   *tete;
    ListElmt		   *queue;
     
    } List;
    Purée, c'est quoi cette présentation à la gomme ? 'indenter', ça te dit quelque chose ?

    Alors mon truc c'est que je sais pas du tout comment dans mon main je vais pouvoir utiliser les structures et les fonctions que j'ai mise (init et destroy) à cause de ces pointeurs de fonction.

    Donc si quelqu'un y arrive ca m'interesse
    Ca c'est pas dur,
    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
     
    #include "list.h"
     
    void cb_detruire (void *donnee)
    {
    }
     
    int main (void)
    {
       List x;
     
       list_init (&x, cb_detruire);
       list_destroy (&x);
     
       return 0;
    }
    mais déjà, il faudrait que ton code compile...
    • Dans list.h, il manque un #endif.
    • Dans list.c,
      Appel de la fonction inconnue list_size
      Appel de la fonction inconnue list_rem_next

  3. #3
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut
    En fait ce code est tiré du bouquin "Maitrise des Algorithme en C" de Kyle Loudon chez O'reilly. Donc je pense que ca doit etre pas mal quand meme non ?
    J'ai acheté ce bouquin pour juste avoir sous la main les Algos de base au cas ou mais tous est fait de cette manière donc j'ai un peu de mal à le suivre dans son raisonnement.

    Edit : L'indentation je connais bien j'ai juste fait un copier/coller des sources fournit avec le bouquin. Je code pas comme ca hein lol (enfin niveau de la présentation de mon code).

  4. #4
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    • Dans list.h, il manque un #endif.
    • Dans list.c,
      Appel de la fonction inconnue list_size
      Appel de la fonction inconnue list_rem_next
      analyse en cours ...
    Sinon Pour tes erreurs c'est normal j'ai mis des extraits du code. Je pensais pas que le code entier était interessant pour ma question.

  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 AuraHxC
    En fait ce code est tiré du bouquin "Maitrise des Algorithme en C" de Kyle Loudon chez O'reilly. Donc je pense que ca doit etre pas mal quand meme non ?
    Oui, j'ai retiré ma diatribe. On est d'accord, c'est correct. Je pensais aux fonctions 'internes'. Désolé.

    Edit : L'indentation je connais bien j'ai juste fait un copier/coller des sources fournit avec le bouquin. Je code pas comme ca hein lol (enfin niveau de la présentation de mon code).
    Ben alors il va falloir apprendre à utiliser un indenteur.

    http://emmanuel-delahaye.developpez....tm#indentation

  6. #6
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut
    Pour l'indentation, je suis d'accord c'est juste que j'ai fait un pur copier/coller du fichier ouvert avec DevC++. La prochaine fois je le referais correctement avant de le poster

  7. #7
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Oué, ça fait peur au debut, mais en fait c'est simple et on peut faire des choses tres puissantes avec.
    D'apres moi c'est un peu l'ancentre de l'heritage

  8. #8
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut
    Citation Envoyé par Gruik
    Oué, ça fait peur au debut, mais en fait c'est simple et on peut faire des choses tres puissantes avec.
    D'apres moi c'est un peu l'ancentre de l'heritage
    C'est vrai que ca fait peur je l'avoue lol.
    J'essaie de comprendre et de faire des tests mais pour l'instant c'est pas très concluant

  9. #9
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    126
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 126
    Par défaut
    Ce code me semble etre une liste chainée.

    J'ai pas tres bien comprise la question au debut et le sujet a semblé avoir dévié vers d'autres chose???

  10. #10
    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
    Salut,

    Voici un lien vers un excellent tutoriel traîtant des pointeurs de fonctions:
    http://www.newty.de/fpt/zip/f_fpt.pdf

    Et un autre sur developpez.com pour une application de ce concept avec la programmation orienté objets en langage C:
    http://chgi.developpez.com/c/objet/

    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++

    +

  11. #11
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    C'est aussi le seul moyen de réaliser des composants logiciels indépendant des sorties.
    Salut,
    ca m'intéresse tu pouurâis expliquer ou donner un lien ?
    merci ^^

  12. #12
    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 Djakisback
    Salut,
    ca m'intéresse tu pouurâis expliquer ou donner un lien ?
    merci ^^
    Voici un lien:
    http://emmanuel-delahaye.developpez.com/complog.htm

    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++

    +

  13. #13
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Hello,
    c'est le même, mais je capte pas pourquoi t'es obligé d'utiliser des pointeurs sur fonction.

  14. #14
    Membre chevronné Avatar de Lunixinclar
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2006
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 416
    Par défaut
    Salut, dans certains cas on n'y est pas obligé.
    http://gd.tuwien.ac.at/languages/c/p...rown/c_106.htm
    dit:
    A pointer is assigned the start address of a function, thus, by typing the pointer name, program execution jumps to the routine pointed to.
    By using a single pointer, many different routines could be executed, simply by re-directing the pointer to point to another function. Thus, programs could use this to send information to a printer, console device, tape unit etc, simply by pointing the pointer associated with output to the appropriate output function!

  15. #15
    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 Djakisback
    Hello,
    c'est le même, mais je capte pas pourquoi t'es obligé d'utiliser des pointeurs sur fonction.
    L'informatique est l'art du traitement de l'information. Elle s'articule autour du principe que j'espère acquis de tous qui est :

    entrée -> traitement -> sortie.

    C'est bien joli, mais en pratique ça se passe comment ?

    La plus petite unité de traitement en langage C est la fonction. Elle dispose d'une interface qui lui permet de recevoir des données en entrée, d'un corps qui permet d'effectuer les traitements et pour sorties, il y a 3 possibilité :

    1. Retourner une valeur (rarement suffisant).
    2. Ecrire dans une variable extérieure dont on a passé l'adresse en paramètre (pas de limite et souvent suffisant).
    3. appeler une autre fonction de traitement appartenant à une autre entité fonctionnelle, ou une fonction de sortie qui va réaliser une sortie vers un dispositif extérieur (ecran, disque, réseau, registres I/O, composant physique mappé en mémoire...)

    Les deux premiers cas sont bien connus et n'appellent pas de commentaires. Le troisième cas est plus intéressant. En effet, du fait de la diversité des sorties, la fonction de sortie que l'on va appeler sera différente selon le contexte d'utilisation de la fonction de traitement.

    D'où l'idée toute simple et une fois de plus pleine de bon sens, de laisser à l'application le soin de fournir la fonction de sortie, et donc d'utiliser un pointeur de fonction pour stocker l'adresse de la dite fonction. C'est la technique dite du 'callback'.

    Ce mécanisme dynamique permet non seulement de rendre le code de la fonction de traitement indépendant de la sortie (donc de le compiler et de le placer en bibliothèque sans connaitre le contexte d'utilisation), mais en plus il permet de centraliser celle-ci en une fonction unique, ce qui constitue un 'point d'observation des données' privilégié (en termes simple, c'est là qu'on met la trace qui permet de vérifier que tout se passe bien). Ca permet aussi la simulation des sorties et donc le test unitaire de la fonction de traitement. En gros, on y branche ce qu'on veut. C'est une sorte de technique de plug-in 'interne'.

    Encore une fois, ce mécanisme n'a rien de révolutionnaire est est appliqué massivement dans les noyau des OS, les couches réseaux et dans les systèmes de type 'évènementielles' comme les GUI.

    On entend souvent dire de façon un peu théorique, 'il faudrait que le code soit modulaire, qu'on puisse tester les blocs séparément, qu'on puisse les réutiliser...' Bien joli tout ça, mais pour que ça devienne une réalité on fait comment ?

    Ce principe de programmation permet la véritable indépendance fonctionelle et par conséquent la véritable modularisation. C'est pour cela qu'elle s'applique à la réalisation des composants logiciels, véritables briques autonomes et validées permettant la construction solide basée sur des mécanismes vérifiés. Le lien entre les briques se fait au niveau applicatif en remplissant correctement les fonction 'callbacks. Souvent, un simple appel de fonction suffit.

    Le développement est ainsi réduit au strict minimum.

  16. #16
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Salut,
    merci pour cette réponse. ^^
    D'après ce que je comprends c'est qu'il s'agit d'une obligation de par son efficacité.
    Bye

    [edit]En fait le seul autre moyen de passer une fonction de callback est qu'elle soit globale et ensuite de faire un test dans la fonction appelante pour savoir quelle callback utiliser, c'est bien ca ?
    Effectivement c'est très nul [/edit]

  17. #17
    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 Djakisback
    D'après ce que je comprends c'est qu'il s'agit d'une obligation de par son efficacité.
    Je ne suis pas sûr d'avoir compris. Disons que c'est une obligation en terme modularité et d'indépendance.
    [edit]En fait le seul autre moyen de passer une fonction de callback est qu'elle soit globale et ensuite de faire un test dans la fonction appelante pour savoir quelle callback utiliser, c'est bien ca ?
    Effectivement c'est très nul [/edit]
    Tu as du te rendre compte que ça rompait le principe d'indépendance en créant un lien statique (une dépendance) entre le composant logiciel et l'application. C'est un non-sens dans la cadre de la programmation modulaire véritable.

  18. #18
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    En effet, cette fois j'ai compris.
    Merci encore pour ces infos.

  19. #19
    Membre éclairé Avatar de AuraHxC
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 652
    Par défaut
    J'avais un peu mis de côté les pointeurs de fonction mais j'ai envie de mis remettre... Donc cette fois je vais mettre le code complet.

    clist.h :
    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
     
    /***************************************clist.h*******************************************/
     
    #ifndef CLIST_H
    #define CLIST_H
     
    /*Structure pour les éléments des listes circulaires*/
     
    typedef struct CListElmt_ {
        void *donnee;
        struct CListElmt_ *suivant;
    } CListElmt;
     
    /*Structure pour les listes circulaires*/
     
    typedef struct CList_ {
        int taille;
        int (*corresp)(const void *val1, const void *val2);
        void (*detruire)(void *donnee);
        CListElmt *tete;
    }CList;
     
    /*Interface Publique*/
     
    void clist_init(CList *liste, void (*detruire)(void *donnee));
    void clist_destroy(CList *liste);
    int clist_ins_next(CList *liste, CListElmt *element, const void *donnee);
    int clist_rem_next(CList *liste, CListElmt *element, void **donnee);
    #define clist_size(liste) ((liste)->taille)
    #define clist_head(liste) ((liste)->tete)
    #define clist_data(element) ((element)->donnee)
    #define clist_next(element) ((element)->suivant)
     
    #endif
    clist.c :

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    /**********************************clist.c******************************/
     
    #include <stdlib.h>
    #include <string.h>
     
    #include "clist.h"
     
    /*********************************clist_init****************************/
     
    void clist_init(CList *liste, void (*detruire)(void *donnee)) {
        liste->taille = 0;
        liste->detruire = detruire;
        liste->tete = NULL;
     
        return;
    }
     
    /********************************clist_destroy**************************/
     
    void clist_destroy(CList *liste) {
        void *donnee;
     
        while (clist_size(liste) > 0) {
            if (clist_rem_next(liste,liste->tete,(void**)&donnee) == 0 && liste->detruire != NULL) {
                liste->detruire(donnee);
            }
        }
     
        memset(liste,0,sizeof(CList));
     
        return;
    }
     
    /*****************************clist_ins_next***************************/
     
    int clist_ins_next(CList *liste, CListElmt *element, const void *donnee) {
        CListElmt *nouv_element;
     
        if ((nouv_element = (CListElmt *)malloc(sizeof(CListElmt))) == NULL)
            return -1;
     
        nouv_element->donnee = (void *)donnee;
     
        if (clist_size(liste) == 0) {
            nouv_element->suivant = nouv_element;
            liste->tete = nouv_element;
        }
        else {
            nouv_element->suivant = element->suivant;
            element->suivant = nouv_element;
        }
     
        liste->taille++;
     
        return 0;
    }
     
    /**************************clist_rem_next****************************/
     
    int clist_rem_next(CList *liste, CListElmt *element, void **donnee) {
        CListElmt *ancien_element;
     
        if (clist_size(liste) == 0)
            return -1;
     
        *donnee = element->suivant->donnee;
     
        if (element->suivant == element) {
            ancien_element = element->suivant;
            liste->tete = NULL;
        }
        else {
            ancien_element = element->suivant;
            element->suivant = element->suivant->suivant;
        }
     
        free(ancien_element);
        liste->taille--;
     
        return 0;
    }
    main.c :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    /************************************main.c**********************************/
     
    #include "clist.h"
     
    int main(void) {
        CList liste;
        clist_init(&liste,clist_destroy);
        return 0;
    }
    Et ca me retourne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    main.c: In function «main":
    main.c:7: attention : passing argument 2 of «clist_init" from incompatible pointer type
    Je pensais qu'il fallait faire comme ça mais apparemment non, donc si quelqu'un peut m'expliquer comment bien comprendre et utiliser ce code ça serait très sympa.

  20. #20
    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 AuraHxC
    J'avais un peu mis de côté les pointeurs de fonction mais j'ai envie de mis remettre... Donc cette fois je vais mettre le code complet.

    <...>Et ca me retourne ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    main.c: In function «main":
    main.c:7: attention : passing argument 2 of «clist_init" from incompatible pointer type
    Je pensais qu'il fallait faire comme ça mais apparemment non, donc si quelqu'un peut m'expliquer comment bien comprendre et utiliser ce code ça serait très sympa.
    On peut faire comme ça pour résoudre ton problème immédiat (oui, il fait être cohérent avec les définitions).
    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
     
     
    /***************************************clist.h*******************************************/
     
    #ifndef CLIST_H
    #define CLIST_H
     
    /*Structure pour les éléments des listes circulaires*/
     
    typedef struct CListElmt
    {
       void *donnee;
       struct CListElmt *suivant;
    }
    CListElmt;
     
    /*Structure pour les listes circulaires*/
     
    typedef struct clist
    {
       int taille;
       int (*corresp) (const void *val1, const void *val2);
       void (*detruire) (struct clist * liste);
       CListElmt *tete;
    }
    CList;
     
    /*Interface Publique*/
     
    void clist_init (CList * liste, void (*detruire) (CList * liste));
    void clist_destroy (CList * liste);
    int clist_ins_next (CList * liste, CListElmt * element, const void *donnee);
    int clist_rem_next (CList * liste, CListElmt * element, void **donnee);
    #define clist_size(liste) ((liste)->taille)
    #define clist_head(liste) ((liste)->tete)
    #define clist_data(element) ((element)->donnee)
    #define clist_next(element) ((element)->suivant)
     
    #endif
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
     
    /**********************************clist.c******************************/
     
    /* toujours en premier */
    #include "clist.h"
     
    #include <stdlib.h>
    #include <string.h>
     
     
    /*********************************clist_init****************************/
     
    void clist_init (CList * liste, void (*detruire) (CList * liste))
    {
       liste->taille = 0;
       liste->detruire = detruire;
       liste->tete = NULL;
     
       return;
    }
     
    /********************************clist_destroy**************************/
     
    void clist_destroy (CList * liste)
    {
       void *donnee;
     
       while (clist_size (liste) > 0)
       {
          if (clist_rem_next (liste, liste->tete, (void **) &donnee) == 0
              && liste->detruire != NULL)
          {
             liste->detruire (donnee);
          }
       }
     
       memset (liste, 0, sizeof (CList));
     
       return;
    }
     
    /*****************************clist_ins_next***************************/
     
    int clist_ins_next (CList * liste, CListElmt * element, const void *donnee)
    {
       CListElmt *nouv_element;
     
       if ((nouv_element = (CListElmt *) malloc (sizeof (CListElmt))) == NULL)
          return -1;
     
       nouv_element->donnee = (void *) donnee;
     
       if (clist_size (liste) == 0)
       {
          nouv_element->suivant = nouv_element;
          liste->tete = nouv_element;
       }
       else
       {
          nouv_element->suivant = element->suivant;
          element->suivant = nouv_element;
       }
     
       liste->taille++;
     
       return 0;
    }
     
    /**************************clist_rem_next****************************/
     
    int clist_rem_next (CList * liste, CListElmt * element, void **donnee)
    {
       CListElmt *ancien_element;
     
       if (clist_size (liste) == 0)
          return -1;
     
       *donnee = element->suivant->donnee;
     
       if (element->suivant == element)
       {
          ancien_element = element->suivant;
          liste->tete = NULL;
       }
       else
       {
          ancien_element = element->suivant;
          element->suivant = element->suivant->suivant;
       }
     
       free (ancien_element);
       liste->taille--;
     
       return 0;
    }
    Mais je ne vois pas l'intérêt d'une tel pointeur de fonction ici, étant donné que la fonction fait partie de la bibliothèque clist. A moins que tu envisages une fonction 'utilisateur'...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. opengl et pointeur de fonction
    Par Oldhar dans le forum C
    Réponses: 5
    Dernier message: 06/11/2003, 23h56
  2. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37
  3. Matrice de pointeurs de fonctions
    Par sebduth dans le forum C
    Réponses: 15
    Dernier message: 18/07/2003, 14h03
  4. [Kylix] Pointeur de fonctions
    Par _dack_ dans le forum EDI
    Réponses: 1
    Dernier message: 03/07/2003, 10h17
  5. pointeur de fonction
    Par kardath dans le forum C
    Réponses: 4
    Dernier message: 28/12/2002, 14h39

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