Functies als parameters in C

Ik ben momenteel bezig met een project van de intro C-klasse, we maken in feite een hash-tabelimplementatie in C, maar mijn huidige vraag heeft betrekking op hoe een bepaalde functie in het codeskelet werd geschreven door mijn professor. Hier is de headerdefinitie van de aanmaakmethode:

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

Dit lijkt verwijzingen naar functies als parameters te zijn? Ik weet niet precies hoe ik dit moet noemen, of wat er gebeurt als het wordt genoemd. Ik weet niet eens zeker waar deze methoden (hash, equals en print) vandaan komen. Alle hulp zou zeer op prijs worden gesteld. Bedankt

1
Wanneer u een aanwijzer naar een functie of array hebt, gebruik dan altijd een typedef als u de optie hebt. Misschien niet in dit geval, maar houd het in gedachten voor de volgende keer dat je zo'n chaos ziet.
toegevoegd de auteur Mooing Duck, de bron

8 antwoord

Ja, dit is een functie die drie functie-aanwijzers als argumenten gebruikt en een aanwijzer naar een tabel retourneert. Om het te gebruiken, zou je drie functies moeten definiëren die aan de gegeven criteria voldoen:

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

en bel dan de functie met hen:

t = create(my_hash, my_equals, my_print);

Dit lijkt erop dat het bedoeld is om een ​​hash-tabel te maken, en je moet het een hash-functie en vergelijkingsfunctie geven. De afdrukfunctie is waarschijnlijk alleen bedoeld voor foutopsporing.

2
toegevoegd

Ja, dit is een functie die drie functie-aanwijzers als argumenten gebruikt en een aanwijzer naar een tabel retourneert. Om het te gebruiken, zou je drie functies moeten definiëren die aan de gegeven criteria voldoen:

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

en bel dan de functie met hen:

t = create(my_hash, my_equals, my_print);

Dit lijkt erop dat het bedoeld is om een ​​hash-tabel te maken, en je moet het een hash-functie en vergelijkingsfunctie geven. De afdrukfunctie is waarschijnlijk alleen bedoeld voor foutopsporing.

2
toegevoegd

Dit lijken wijzers naar functies als parameters te zijn?

Ja.

Ik weet niet zeker hoe ik dit moet noemen

Om de functie create op te roepen, geeft u de adressen van sommige functies door met de juiste typen om create aan te roepen:

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

of wat er gebeurt als het wordt aangeroepen.

Elke plaats in de body van create waar (*) de puntige functie wordt aangeroepen, wordt de eigenlijke functie (bijvoorbeeld f1 ) uiteindelijk aangeroepen met de opgegeven argumenten. Het kan (* is gelijk aan) (k1, k2); zijn als een fictief voorbeeld dat zich binnen create zou kunnen hebben voorgedaan.

(*) of, in dit geval, een andere functie die de functie-aanwijzers krijgt van de structuur toegewezen door create waar deze ze zal hebben opgeslagen


In feite staat C je toe om create (f1, f2, f3); in de eerste case te schrijven en is gelijk aan (k1, k2); in de tweede, maar dat is gewoon een gemak.

2
toegevoegd
@DanielMoody Functiewijzers zijn vreemd in C, omdat ze automatisch in beide richtingen worden geconverteerd. Ik weet niet of ik dit moet zeggen, maar bekijk voorbeeld 4 in cs.berkeley.edu/~necula/cil/cil016.html . Hoe dan ook, kies gewoon een stijl waar je je prettig bij voelt tussen create (& f1 .../(* is gelijk aan) (k1 ... en create (f1 .../is gelijk aan (k1 ... en probeer blijf erbij, maar wees niet verbaasd als je geen compilerwaarschuwingen krijgt als je een & of een * vergeet voor een functie of functie aanwijzer.
toegevoegd de auteur Pascal Cuoq, de bron
Ja, bedankt dat dit veel logischer is. De syntaxis van deze look zo vreemd dat ik niet wist wat ik ermee moest doen, of zelfs hoe ik het moest opzoeken
toegevoegd de auteur Daniel Moody, de bron

Dit lijken wijzers naar functies als parameters te zijn?

Ja.

Ik weet niet zeker hoe ik dit moet noemen

Om de functie create op te roepen, geeft u de adressen van sommige functies door met de juiste typen om create aan te roepen:

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

of wat er gebeurt als het wordt aangeroepen.

Elke plaats in de body van create waar (*) de puntige functie wordt aangeroepen, wordt de eigenlijke functie (bijvoorbeeld f1 ) uiteindelijk aangeroepen met de opgegeven argumenten. Het kan (* is gelijk aan) (k1, k2); zijn als een fictief voorbeeld dat zich binnen create zou kunnen hebben voorgedaan.

(*) of, in dit geval, een andere functie die de functie-aanwijzers krijgt van de structuur toegewezen door create waar deze ze zal hebben opgeslagen


In feite staat C je toe om create (f1, f2, f3); in de eerste case te schrijven en is gelijk aan (k1, k2); in de tweede, maar dat is gewoon een gemak.

2
toegevoegd
@DanielMoody Functiewijzers zijn vreemd in C, omdat ze automatisch in beide richtingen worden geconverteerd. Ik weet niet of ik dit moet zeggen, maar bekijk voorbeeld 4 in cs.berkeley.edu/~necula/cil/cil016.html . Hoe dan ook, kies gewoon een stijl waar je je prettig bij voelt tussen create (& f1 .../(* is gelijk aan) (k1 ... en create (f1 .../is gelijk aan (k1 ... en probeer blijf erbij, maar wees niet verbaasd als je geen compilerwaarschuwingen krijgt als je een & of een * vergeet voor een functie of functie aanwijzer.
toegevoegd de auteur Pascal Cuoq, de bron
Ja, bedankt dat dit veel logischer is. De syntaxis van deze look zo vreemd dat ik niet wist wat ik ermee moest doen, of zelfs hoe ik het moest opzoeken
toegevoegd de auteur Daniel Moody, de bron

Dit lijken wijzers naar functies als parameters te zijn?

Ja. Dat is juist.

Ik weet niet precies hoe ik dit moet noemen of wat er gebeurt als het wordt aangeroepen.

U moet functies gebruiken die voldoen aan de signat ures van de parameters en bel create met behulp van die functies. Voorbeeld:

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


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

Wat create doet met die functie hangt ervan af, kan alleen maar worden geraden. Ik heb geen idee wat het ermee doet.

1
toegevoegd

Dit lijken wijzers naar functies als parameters te zijn?

Ja. Dat is juist.

Ik weet niet precies hoe ik dit moet noemen of wat er gebeurt als het wordt aangeroepen.

U moet functies gebruiken die voldoen aan de signat ures van de parameters en bel create met behulp van die functies. Voorbeeld:

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


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

Wat create doet met die functie hangt ervan af, kan alleen maar worden geraden. Ik heb geen idee wat het ermee doet.

1
toegevoegd

Dit zou een opmerking moeten zijn - te gabby om te passen

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

Aangezien dit wijzers zijn, zijn de eigenlijke functienamen namen die u maakt (of de prof heeft ze mogelijk voor u gemaakt met een willekeurige naam, inclusief hash, equals en print).

Maar "hash" retourneert een verschuiving naar een hash-tabel (misschien een array). "gelijk aan" test of twee invoerwaarden dezelfde hash zijn - gelijkheid kan puur subjectief zijn. Vraag het je prof. print geeft een hash-invoer weer, wat betekent dat ik veronderstel dat het de invoer vindt en de informatie in de gehashte array of het object voor de sleutelwaarde afdrukt. Zoek 'associatieve array' op om te zien wat ik bedoel.

1
toegevoegd
Opmerkingen mogen normaal gesproken niet als antwoorden worden geplaatst, maar dit is niet zo slecht als een antwoord, dus ik heb niet gemerkt of getalmd.
toegevoegd de auteur Mooing Duck, de bron

Dit zou een opmerking moeten zijn - te gabby om te passen

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

Aangezien dit wijzers zijn, zijn de eigenlijke functienamen namen die u maakt (of de prof heeft ze mogelijk voor u gemaakt met een willekeurige naam, inclusief hash, equals en print).

Maar "hash" retourneert een verschuiving naar een hash-tabel (misschien een array). "gelijk aan" test of twee invoerwaarden dezelfde hash zijn - gelijkheid kan puur subjectief zijn. Vraag het je prof. print geeft een hash-invoer weer, wat betekent dat ik veronderstel dat het de invoer vindt en de informatie in de gehashte array of het object voor de sleutelwaarde afdrukt. Zoek 'associatieve array' op om te zien wat ik bedoel.

1
toegevoegd
Opmerkingen mogen normaal gesproken niet als antwoorden worden geplaatst, maar dit is niet zo slecht als een antwoord, dus ik heb niet gemerkt of getalmd.
toegevoegd de auteur Mooing Duck, de bron