Bonjour,
Je voudrai être sûr d'avoir compris les pointeurs de fonctions et la généricité en C. Pour être sûr d'avoir compris, est ce que quelqu'un qui connait bien le C pourrait me dire si ce que je dis est bien (c'est bien ) ou mal (bahhhh c'est mal ) ?
Merci par avance !!!!
Donc, si j'ai bien tout lu Freud :
(*) si je veux faire une fonction générique qui traite des données indépendamment de leur type je peux utiliser, préférablement, deux solutions.
1) Je fait une fonction qui renvoie un void *, qui sera alloué dans la fonction. Par exemple, le prototype serait :
Code :
- void * ma_fonction(int i, void * data, size_t size, size_t numel, void (*f) (void *, ...) );
|
où la variable i permet de choisir les cas à traiter, data est les données passées en entrée, size la taille du type de data (int, double, etc) et numel le nombre d'élement, numel > 1 si c'est un tableau d'éléments. La fonction renvoie un void *, pointeur vers un bloc mémoire alloué à l'intérieur de la fonction ma_fonction().
2) Utiliser une union pour que la fonction renvoie la solution dans cette union. Par exemple, je crée une union :
Code :
- union mon_union {
- int a;
- double b;
- double ** c;
- //etc ...
- };
|
et le prototype de ma fonction générique serait alors :
Code :
- void ma_fonction(int i, void * data, size_t size, size_t numel, void (*f) (void *, ...), union mon_union * res );
|
et dans ce cas, à l'intérieur de ma_fonction(), je renvoie le resultat sur le membre de l'union correspondant. Par exemple, si je renvoie un tableau de double, je ferai, à l'intérieur de ma_fonction() :
Code :
- double * resultat = malloc(sizeof(double) * numel);
- //on remplit le tableau
- *res->c = resultat;
|
(*) Les choses que je ne peut pas faire, sont de renvoyer le résultat dans un void * où même un void **, car void* n'est pas déréférençable.
Par exemple, si mon prototype de fonction générique est :
Code :
- void ma_fonction(int i, void * data, size_t size, size_t numel, void * res);
|
ça ne sera pas bon, car si je renvoie une valeur dans le résultat, je serai obligé de faire, à l'intérieur de la fonction :
Code :
- *res = 1; //dans l'exemple ou la valeur de résultat est 1
|
Au pire, je pourrais le faire avec un memcpy() dans le cas ou j'ai void **
Une autre petite question si c'est possible .. :
Je ne comprend pas vraiment l'interêt d'utiliser des pointeurs de fonctions, dans une fonction, si au final on a quand même un paramètre qui dit quelle cas on est censé traiter, par exemple, si on a
Code :
- void ma_fonction(int cas_a_traiter, void * data, size_t size, size_t numel, void (*f) (void * , void * ) );
|
on fait un swithc dans la fonction pour dire que on traite tel ou tel cas :
Code :
- switch(cas_a_traiter) {
- case 1:
- //on fait les traitement avec la fonction f dont l'adresse est passée en arguement
- printf("resultat=%d", blabla_i); //par exemple on est dans le cas ou on traite des entiers
- case 2:
- //on fait les traitement avec la fonction f dont l'adresse est passée en arguement
- printf("resultat=%f", blabla_f); //par exemple on est dans le cas ou on traite des float
- //etc
- }
|
Ne serait-ce pas aussi facile de ne pas utiliser de pointeur de fonction et d'appeler une fonction différente dans chacun des cas du case :
Code :
- switch(cas_a_traiter) {
- case 1:
- fonction_qui_traite_des_int(); //on fait les traitement avec la fonction f dont l'adresse est passée en arguement
- printf("resultat=%d", blabla_i); //par exemple on est dans le cas ou on traite des entiers
- case 2:
- fonction_qui_traite_des_float(); //on fait les traitement avec la fonction f dont l'adresse est passée en arguement
- printf("resultat=%f", blabla_f); //par exemple on est dans le cas ou on traite des float
- //etc
- }
|
et dans ce cas on a juste
Code :
- void ma_fonction(int cas_a_traiter, void * data, size_t size, size_t numel );
|
Merci par avance