Aller au contenu

[Langage C] Pointeurs de fonction


Messages recommandés

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 :yes:

/**************************************************************
*															 *
*  ------------------------- 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);

/************************************************************
*														   *
*  ------------------------ 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 :mdr:

Merci d'avance.

EDIT : Je précise que c'est un extrait du code donc pas la peine de le prendre et de la compilé. Parce que j'ai posé la meme question sur developpez.com et on me sort , ton code ne compile pas il te manque un #ENDIF dans ton .h et il me sort kil y a des fonctions qui n'existe pas... Oui c'est normal :transpi:

Lien vers le commentaire
Partager sur d’autres sites

où comment faire de l'objet avec un langage non-orienté objet :eeek2:

admettons que tu aies un void * donnee appartenant à la liste myliste. Si tu veux détruire cette donnée, il te suffira d'appeler

(myliste->detruire)(donnee);

un peu à la manière d'un langage objet où tu aurais appelé la méthode

myliste->detruire(donnée);

LE seul incovéniant de cette pseudo programmation objet, c'est que le pointeur implicite this (référençant l'instance dont on appelle la méthode) n'est pas systématiquement passé en premier argument. Donc si tu veux faire une fonction (méthode) qui modifie un des champ de la structure, il va falloir explicitement passer ta structure en argument. Par exemple (mylist->inserer_en_tete)(myliste, donnee);

voilou :eeek2:

Lien vers le commentaire
Partager sur d’autres sites

Lorinc je te file par exemple le list.h entier... Est ce que tu peux me faire un exemple de main ou tu crées une liste et que tu rajoute genre 3 élements a cette liste...

/**************************************************************
*															 *
*  ------------------------- 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);

int list_ins_next(List *liste, ListElmt *element, 
			  const void *donnee);

int list_rem_next(List *liste, ListElmt *element, 
			  void **donnee);

#define list_size(liste) ((liste)->taille)

#define list_head(liste) ((liste)->tete)

#define list_tail(liste) ((liste)->queue)

#define list_is_head(liste, element)\
				  ((element) == (liste)->tete ? 1 : 0) 

#define list_is_tail(element)\
				  ((element)->suivant == NULL ? 1 : 0)

#define list_data(element) ((element)->donnee)

#define list_next(element) ((element)->suivant)

#endif

Merci d'avance parce que la j'arrive pas a faire un truc concluant a vrai dire :eeek2:

J'espere que je t'en demande pas de trop lol

Lien vers le commentaire
Partager sur d’autres sites

Je ne vais pas te donner la réponse entière mais quelques pistes:

- lorinc parle d'Object car en fait ta structure ListElmt est générique, à savoir que tu peux y stocker un pointeur sur n'importe quel type de donnée: void * donnee -> typage faible qui te permet de mettre n'importe quoi(après un cast explicite)

- ListElmt est un conteneur générique comme vu plus haut, et visiblement dans ton design la structure de stockage List_ doit être capable de libérer l'espace mémoire occupé par void * donnee.

Tu dois comprendre que ton conteneur générique ListElmt ne connait pas la nature de ton void * donnee, elle ne sait pas naturellement comment libérer l'espace mémoire occupé.

C'est pourquoi à la construction de ton conteneur de liste List_ nécessite un "constructeur": list_init.

Ce constructeur sert principalement à indiquer la fonction qui te permettra de détruire tes contenus et de libérer l'espace mémoire utilisé.

Cette fonction de destruction est déterminée par le passage du pointeur sur fonction void (*detruire)(void *donnee).

Par example si tu stockes des tableaux d'entiers:

void free_int_array(void * myIntP)

{

int * p = (int *) myIntP;

/* code de libération de la mémoire

....

*/

}

A l'intialisation de ta liste tu appelleras:

list_init(pList , &free_int_array);

Sachant que ton ListElmt stockera des tableaux d'entiers libérables par free_int_array:

int * pIntArray;

ListElmt * myListElmt;

... intialisations ...

myListElmt -> donnee = (void *)pIntArray;

Voilà je suis un peu rouillé en C alors il peut y avoir des coquilles mais l'idée est là.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...