Fonctionne comme paramètre en C

Je travaille actuellement sur un projet d'introduction à la classe C; nous créons une implémentation d'une table de hachage en C, mais ma question actuelle porte sur la manière dont une certaine fonction a été écrite dans le squelette de code fourni par mon professeur. Voici la définition de l'en-tête de la méthode create:

     Table* create(long (*hash)(void* key),
          bool (*equals)(void* key1, void* key2),
          void (*print)(void* key1, void* key2));

Cela semble être des pointeurs vers des fonctions en tant que paramètres? Je ne sais même pas comment appeler cela, ni ce qui se passe quand on l'appelle. Je ne sais même pas d'où proviennent ces méthodes (hachage, égaux et impression). Toute aide serait grandement appréciée. Merci

1
Lorsque vous avez un pointeur sur une fonction ou un tableau, utilisez toujours un typedef lorsque vous avez l'option. Vous ne pouvez pas dans ce cas, mais gardez cela à l'esprit pour la prochaine fois que vous verrez un tel chaos.
ajouté l'auteur Mooing Duck, source

8 Réponses

Oui, il s'agit d'une fonction qui prend trois pointeurs de fonction en tant qu'arguments et renvoie un pointeur sur une table. Pour l'utiliser, vous devez définir trois fonctions répondant aux critères donnés:

long my_hash(void *key) { ... }
bool my_equals(void *key1, void *key2) { ... }
void my_print(void *key1, void *key2) { ... }

puis appelez la fonction avec eux:

t = create(my_hash, my_equals, my_print);

Cela ressemble à la création d'une table de hachage et vous devez lui attribuer une fonction de hachage et une fonction de comparaison. La fonction d'impression est probablement juste pour le débogage.

2
ajouté

Oui, il s'agit d'une fonction qui prend trois pointeurs de fonction en tant qu'arguments et renvoie un pointeur sur une table. Pour l'utiliser, vous devez définir trois fonctions répondant aux critères donnés:

long my_hash(void *key) { ... }
bool my_equals(void *key1, void *key2) { ... }
void my_print(void *key1, void *key2) { ... }

puis appelez la fonction avec eux:

t = create(my_hash, my_equals, my_print);

Cela ressemble à la création d'une table de hachage et vous devez lui attribuer une fonction de hachage et une fonction de comparaison. La fonction d'impression est probablement juste pour le débogage.

2
ajouté

Cela semble être des pointeurs vers des fonctions en tant que paramètres?

Oui.

Je ne sais même pas comment appeler cela

Pour appeler la fonction create , transmettez les adresses de certaines fonctions avec les types appropriés pour appeler create :

create(&f1, &f2, &f3);

ou ce qui se passe quand on l'appelle.

Toute place dans le corps de create où (*) la fonction pointée est invoquée, la fonction réelle (par exemple, f1 ) est appelée avec les arguments fournis. Cela pourrait être (* égal à) (k1, k2); comme exemple fictif qui aurait pu se produire dans create .

(*) ou, dans ce cas, une autre fonction qui obtiendra les pointeurs de fonction de la structure allouée par create où elle les aura stockés


En fait, C vous permet d’écrire create (f1, f2, f3); dans le premier cas et égal à (k1, k2); dans le second, mais commodité.

2
ajouté
@DanielMoody Les pointeurs de fonction sont étranges en C, car ils se convertissent automatiquement dans les deux sens. Je ne sais pas si je devrais vous dire ceci, mais regardez l'exemple 4 dans cs.berkeley.edu/~necula/cil/cil016.html . Quoi qu’il en soit, il suffit de choisir un style qui vous convient entre create (& f1…/(* est égal à) (k1… et create (f1…/est égal à (k1… respectez-le, mais ne soyez pas surpris si vous ne recevez pas les avertissements du compilateur lorsque vous oubliez un & ou un * pour une fonction ou un pointeur de fonction.
ajouté l'auteur Pascal Cuoq, source
Oui, merci, cela a beaucoup plus de sens. La syntaxe de ce look si étrange que je ne savais pas quoi en faire, ni même comment la rechercher
ajouté l'auteur Daniel Moody, source

Cela semble être des pointeurs vers des fonctions en tant que paramètres?

Oui.

Je ne sais même pas comment appeler cela

Pour appeler la fonction create , transmettez les adresses de certaines fonctions avec les types appropriés pour appeler create :

create(&f1, &f2, &f3);

ou ce qui se passe quand on l'appelle.

Toute place dans le corps de create où (*) la fonction pointée est invoquée, la fonction réelle (par exemple, f1 ) est appelée avec les arguments fournis. Cela pourrait être (* égal à) (k1, k2); comme exemple fictif qui aurait pu se produire dans create .

(*) ou, dans ce cas, une autre fonction qui obtiendra les pointeurs de fonction de la structure allouée par create où elle les aura stockés


En fait, C vous permet d’écrire create (f1, f2, f3); dans le premier cas et égal à (k1, k2); dans le second, mais commodité.

2
ajouté
@DanielMoody Les pointeurs de fonction sont étranges en C, car ils se convertissent automatiquement dans les deux sens. Je ne sais pas si je devrais vous dire ceci, mais regardez l'exemple 4 dans cs.berkeley.edu/~necula/cil/cil016.html . Quoi qu’il en soit, il suffit de choisir un style qui vous convient entre create (& f1…/(* est égal à) (k1… et create (f1…/est égal à (k1… respectez-le, mais ne soyez pas surpris si vous ne recevez pas les avertissements du compilateur lorsque vous oubliez un & ou un * pour une fonction ou un pointeur de fonction.
ajouté l'auteur Pascal Cuoq, source
Oui, merci, cela a beaucoup plus de sens. La syntaxe de ce look si étrange que je ne savais pas quoi en faire, ni même comment la rechercher
ajouté l'auteur Daniel Moody, source

Cela semble être des pointeurs vers des fonctions en tant que paramètres?

Oui. C'est correct.

Je ne sais pas comment appeler cela, ni ce qu'il se passe quand on l'appelle.

Vous aurez besoin d'utiliser des fonctions qui répondent à la signature des paramètres et appelez create en utilisant ces fonctions. Exemple:

long myHashFunction(void* key) {...}
bool myEqualsFunction(void* key1, void* key2) {...}
void myPrintFunction(void* key1, void* key2)) {...}


Table* table = create(myHashFunction, myEqualsFunction, myPrintFunction);

Ce que create fait avec ces fonctions dépend ne peut être que deviné. Je n'ai aucune idée de ce que ça fait d'eux.

1
ajouté

Cela semble être des pointeurs vers des fonctions en tant que paramètres?

Oui. C'est correct.

Je ne sais pas comment appeler cela, ni ce qu'il se passe quand on l'appelle.

Vous aurez besoin d'utiliser des fonctions qui répondent à la signature des paramètres et appelez create en utilisant ces fonctions. Exemple:

long myHashFunction(void* key) {...}
bool myEqualsFunction(void* key1, void* key2) {...}
void myPrintFunction(void* key1, void* key2)) {...}


Table* table = create(myHashFunction, myEqualsFunction, myPrintFunction);

Ce que create fait avec ces fonctions dépend ne peut être que deviné. Je n'ai aucune idée de ce que ça fait d'eux.

1
ajouté

Cela devrait être un commentaire - trop gabby pour s'adapter

Those are function pointers:
          long (*hash)(void* key),  <- returns a long, uses a void * as input
          bool (*equals)(void* key1, void* key2), <- return 0 or 1            (True/False)
          void (*print)(void* key1, void* key2)); <- no return

Etant donné que ce sont des pointeurs, les noms de fonction réels sont des noms que vous créez (ou le prof peut vous les avoir créés avec n’importe quel nom, y compris un hachage, un égal et un imprimé).

Mais "hash" renvoie un décalage dans une table de hachage (peut-être un tableau). "equals" teste si deux valeurs d'entrée sont identiques, une similitude peut être purement subjective. Demandez à votre prof. print affiche une entrée de hachage, ce qui signifie que je suppose, trouve l’entrée et affiche les informations dans le tableau ou l’objet haché pour la valeur de clé. Recherchez «tableau associatif» pour voir ce que je veux dire.

1
ajouté
Normalement, les commentaires ne doivent pas être postés comme réponses, mais ce n’est pas une si mauvaise réponse, c’est pourquoi je n’ai ni marqué ni voté.
ajouté l'auteur Mooing Duck, source

Cela devrait être un commentaire - trop gabby pour s'adapter

Those are function pointers:
          long (*hash)(void* key),  <- returns a long, uses a void * as input
          bool (*equals)(void* key1, void* key2), <- return 0 or 1            (True/False)
          void (*print)(void* key1, void* key2)); <- no return

Etant donné que ce sont des pointeurs, les noms de fonction réels sont des noms que vous créez (ou le prof peut vous les avoir créés avec n’importe quel nom, y compris un hachage, un égal et un imprimé).

Mais "hash" renvoie un décalage dans une table de hachage (peut-être un tableau). "equals" teste si deux valeurs d'entrée sont identiques, une similitude peut être purement subjective. Demandez à votre prof. print affiche une entrée de hachage, ce qui signifie que je suppose, trouve l’entrée et affiche les informations dans le tableau ou l’objet haché pour la valeur de clé. Recherchez «tableau associatif» pour voir ce que je veux dire.

1
ajouté
Normalement, les commentaires ne doivent pas être postés comme réponses, mais ce n’est pas une si mauvaise réponse, c’est pourquoi je n’ai ni marqué ni voté.
ajouté l'auteur Mooing Duck, source