salut :
je me demande comment passer un tableau comme argument d'une fonction à condition que la fst modifie réellement les valeurs du tableau (passage par adresse) et merci
salut :
je me demande comment passer un tableau comme argument d'une fonction à condition que la fst modifie réellement les valeurs du tableau (passage par adresse) et merci
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
resalut :
tu as toute à fait raison d'utiliser la phrase "" Et au risque de paraître un peu cinglant, tu pourrais lire les bases du C avant de venir ici...""
car ce que je cherche réellement à savoir c'est le suivant :
si on utilise des pointeurs pour mémoriser voir manipuler des variables par leurs adresses je me demande donc qu'il est l'interet des pointeurs sur des fcts
et merci
Pour te donner un exemple de l'utilité des pointeurs de fonctions, regarde la fonction qsort() et comprend par toi même.
Cordialement.
Bah... tu aurais pu le demander de suite.
Nicolas Sitbon t'as parlé de qsort() qui est une fonction de tri universel et qui a donc besoin, pour trier des éléments qu'elle ne connait pas à l'avance, de recevoir un pointeur sur la fonction qui sert à comparer 2 éléments => ainsi elle peut se servir du pointeur pour appeler la fonction chaque fois qu'elle a besoin de comparer 2 éléments.
Donc, pour simplifier, on utilise un pointeur de fonction chaque fois qu'on ne sait pas à l'avance quelle fonction on utilisera dans un cas particulier.
Par exemple, une fois, j'ai dû faire une appli où l'utilisateur pouvait choisir à l'avance les impressions qu'il voulait lancer. Il commençait par choisir ses impression puis une fois sélectionnées, il les lançait toutes d'un coup.
J'avais donc une fonction dédiée à chaque impression. A chaque impression choisie, je stockais le pointeur associé à la fonction dans un tableau de pointeurs de fonctions.
Une fois l'ensemble validé, je n'avais plus qu'à traiter mon tableau en appelant les pointeurs de fonctions les uns après les autres => les fonctions associées étaient appelées automatiquement.
C'est un exemple comme un autre...
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
La dernière fois que j'ai utilisé des pointeurs sur fonctions, c'était pour gérer le traitement des trames reçues et envoyées dans une application client/serveur. Voici un bout de code utilisé pour créer les trames qui peut t'aider à comprendre.
1º/ Une structure pour identifier quelle fonction doit être appelée au regard de l'ID de la trame à créer2º/ Un tableau contenant les différents ID et fonctions correspondantes (3 trames dans ce cas pour simplifier)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 typedef struct _FORMATTER { char idframe; void (*function)(void *dest_struct, va_list args); } FORMATTER;3º/ Une fonction qui permet de recupérer un pointeur sur fonction au regard de l'ID de la trame
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 const FORMATTER formatters[] = { { ID_CONNECTION, fb_connection }, { ID_DOWNLOAD, fb_downres }, { ID_CHKSUM, fb_chksum } };Et maintenant, l'appel
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void *get_formatter(const char idframe) { int i; for(i = 0; i < 3; i++) if(formatters[i].idframe == idframe) return formatters[i].function; return NULL; }Les fonctions fb_connection, fb_downres et fb_chksum se chargent de créer les trames.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 void (*function)(void *, va_list); function = get_formatter(idframe); function(dest_struct, args);
Joli exemple mais le jour où tu passes à 4 trames, te faut modifier le code 1) dans ton tableau "formatters" et 2) dans ta boucle
Avec un pointeur terminal tu évites ce pb
Et la recherche
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 const FORMATTER formatters[] = { { ID_CONNECTION, fb_connection }, { ID_DOWNLOAD, fb_downres }, { ID_CHKSUM, fb_chksum }, { 0, NULL } };Le jour où tu passes à 4 trames, tu rajoutes juste une ligne dans le tableau "formatters" et pis c'est tout...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 void *get_formatter(const char idframe) { FORMATTER *pt_frame; for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++) { if(pt_frame->idframe == idframe) return pt_frame->function; return NULL; }
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Sauf que ce code :
est faux!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 void *get_formatter(const char idframe) { FORMATTER *pt_frame; for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++) { if(pt_frame->idframe == idframe) return pt_frame->function; return NULL; }
Un pointeur générique ne peut pointer sur une fonction.
Après correction :
ou bien
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 void (*get_formatter(const char idframe))(void *, va_list) { FORMATTER *pt_frame; for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++) { if(pt_frame->idframe == idframe) return pt_frame->function; return NULL; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 typedef void (*MONTYPE)(void *, va_list); MONTYPE get_formatter(const char idframe) { FORMATTER *pt_frame; for(pt_frame=formatters; pt_frame->function != NULL; pt_frame++) { if(pt_frame->idframe == idframe) return pt_frame->function; return NULL; }
pas forcément :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 void (*get_formatter(const char idframe))(void *, va_list) { for(int i = 0; i < (sizeof formatters)/(sizeof formatters[0]); i++) if(formatters[i].idframe == idframe) return formatters[i].function; return NULL; }
En effet c'est un problème que je n'avais pas trouvé comment résoudre. Bien pensé, ton astuce.Pourtant gcc -Wall me l'accepte sans problèmes à la compilation et à l'exécution le code fonctionne. Mais c'est vrai que la déclarationEnvoyé par nicolas.sitbon
est plus explicite.
Code : Sélectionner tout - Visualiser dans une fenêtre à part void (*get_formatter(const char idframe))(void *, va_list)Je ne suis pas sur que ce code fonctionne. Je testerai mais il me semble que j'avais essayé et que la valeur retournée est incorrecte.
Code : Sélectionner tout - Visualiser dans une fenêtre à part for(int i = 0; i < sizeof formatters; i++)
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
oui pardon :
et sizeof renvoi le nombre de bytes pas d'octet.
Code : Sélectionner tout - Visualiser dans une fenêtre à part for(int i = 0; i < (sizeof formatters)/(sizeof formatters[0]); i++)
[QUOTE=nicolas.sitbon;2634394]oui pardon :
En théorie, cet algo de boucle fonctionne parfaitement. Cependant je ne l'aime pas parce que le jour où "formatters" devient un pointeur passé en paramètre sur un tableau de type FORMATTER, ben sizeof renvoie la taille du pointeur et non plus la taille du tableau et là
Code : Sélectionner tout - Visualiser dans une fenêtre à part for(int i = 0; i < (sizeof formatters)/(sizeof formatters[0]); i++)
Donc j'ai la faiblesse de penser que mon idée de null terminaison est la plus souple d'emploi et la plus facilement adaptable à toutes les situations
Bien vu (http://fr.wikipedia.org/wiki/Byte)![]()
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Un autre exemple très répandu (valable dans tous les outils graphiques de nos jours)
Un outil possède un objet "bouton", qui possède une "méthode" OnClick.
Par définition, cet objet ne SAIT pas quelle est la fonction (si il y en a une) qui sera appelée, puisqu'elle dépend de l'utilisateur et de l'appli.
Dans le code de l'objet, il y a donc un :
J'ai utilisé cela à de nombreuses reprises (par exemple faie une biblothèque pour fabriquer des serveurs, où les actions sont identifiées, mais pas la réalisation : par exemple avoir plusieurs serveurs simultanés sur des bases gérées par des outils différents), mais aussi des applis avec des "plugins", etc etc..
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 if ( If_There_Is_A_Function_For_OnClick(Objet) ) Objet.OnClickFunction (...) ;
Partager