Hoe geef je een functie door als parameter in C?

Ik wil een functie maken die een functie uitvoert die door een parameter is doorgegeven op een set gegevens. Hoe geef je een functie door als parameter in C?


Antwoord 1, autoriteit 100%

Verklaring

Een prototype voor een functie die een functieparameter nodig heeft, ziet er als volgt uit:

void func ( void (*f)(int) );

Hierin staat dat de parameter feen verwijzing zal zijn naar een functie die een voidretourtype heeft en die een enkele intparameter nodig heeft . De volgende functie (print) is een voorbeeld van een functie die als parameter aan funckan worden doorgegeven omdat het het juiste type is:

void print ( int x ) {
  printf("%d\n", x);
}

Functie-oproep

Bij het aanroepen van een functie met een functieparameter, moet de doorgegeven waarde een pointer naar een functie zijn. Gebruik hiervoor de functienaam (zonder haakjes):

func(print);

zou funcaanroepen en de afdrukfunctie eraan doorgeven.

Functielichaam

Zoals bij elke parameter, kan funcnu de naam van de parameter in de hoofdtekst van de functie gebruiken om toegang te krijgen tot de waarde van de parameter. Laten we zeggen dat funcde functie die het wordt doorgegeven aan de getallen 0-4 zal toepassen. Overweeg eerst hoe de lus eruit zou zien om direct print aan te roepen:

for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
  print(ctr);
}

Aangezien funcS-parameterverklaring zegt dat fde naam is voor een aanwijzer op de gewenste functie, herinneren we eerst dat als fIs een aanwijzer dan *fis het ding dat fPunten naar (dwz de functie printin dit geval). Als gevolg hiervan, vervang gewoon alle optreden van afdrukken in de lus hierboven met *f:

void func ( void (*f)(int) ) {
  for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
    (*f)(ctr);
  }
}

bron


2, Autoriteit 17%

Deze vraag heeft al het antwoord voor het definiëren van functiewijzers, maar ze kunnen erg rommelig worden, vooral als u ze door uw aanvraag zult passeren. Om deze onaangenaamheid te voorkomen, raad ik aan dat u de functie-aanwijzer in iets leesbaar is. Bijvoorbeeld.

typedef void (*functiontype)();

Verklaar een functie die leeg is en geen argumenten aanneemt. Om een ​​functie-aanwijzer op dit type te maken, kunt u nu doen:

void dosomething() { }
functiontype func = &dosomething;
func();

Voor een functie die een INT retourneert en een char aanneemt die u zou doen

typedef int (*functiontype2)(char);

en om het te gebruiken

int dosomethingwithchar(char a) { return 1; }
functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

Er zijn bibliotheken die kunnen helpen bij het omzetten van functiewijzers in goed leesbare typen. De bibliotheek boost-functieis geweldig en is de moeite waard inspanning!

boost::function<int (char a)> functiontype2;

is zoveel mooier dan het bovenstaande.


Antwoord 3, autoriteit 12%

Sinds C++11 kunt u de functionele bibliotheekgebruiken om dit op een beknopte en generieke manier. De syntaxis is bijvoorbeeld

std::function<bool (int)>

waarbij boolhier het retourtype is van een functie met één argument waarvan het eerste argument van het type intis.

Ik heb hieronder een voorbeeldprogramma toegevoegd:

// g++ test.cpp --std=c++11
#include <functional>
double Combiner(double a, double b, std::function<double (double,double)> func){
  return func(a,b);
}
double Add(double a, double b){
  return a+b;
}
double Mult(double a, double b){
  return a*b;
}
int main(){
  Combiner(12,13,Add);
  Combiner(12,13,Mult);
}

Soms is het echter handiger om een sjabloonfunctie te gebruiken:

// g++ test.cpp --std=c++11
template<class T>
double Combiner(double a, double b, T func){
  return func(a,b);
}
double Add(double a, double b){
  return a+b;
}
double Mult(double a, double b){
  return a*b;
}
int main(){
  Combiner(12,13,Add);
  Combiner(12,13,Mult);
}

4

Functies kunnen worden “doorgegeven” als functiewijzers, volgens ISO C11 6.7.6.3p8: “Een verklaring van een parameter als ” functie retourtype ” wordt aangepast aan ” POINTER TOT FUNCTIE TRUS TYPE ” , zoals in 6.3.2.1. “. Dit bijvoorbeeld:

void foo(int bar(int, int));

komt overeen met dit:

void foo(int (*bar)(int, int));

5

U moet een functie pointer . De syntaxis is een beetje omslachtig, maar het is erg krachtig als je er eenmaal mee krijpt.


6

Ik zal uitleggen met een eenvoudige voorbeeldcode die een comparefunctie als parameter naar een andere sortingfunctie.
Laten we zeggen dat ik een functie voor het sorteren van bellen heb die een aangepaste vergelijkingsfunctie gebruikt en deze gebruikt in plaats van een vaste if-instructie.

Functie vergelijken

bool compare(int a, int b) {
    return a > b;
}

Nu, de Bubble-sortering die een andere functie als parameter gebruikt om een vergelijking uit te voeren

Bubbelsorteerfunctie

void bubble_sort(int arr[], int n, bool (&cmp)(int a, int b)) {
    for (int i = 0;i < n - 1;i++) {
        for (int j = 0;j < (n - 1 - i);j++) {
            if (cmp(arr[j], arr[j + 1])) {
                swap(arr[j], arr[j + 1]);
            }
        }
    }
}

Ten slotte de maindie de functie Bubble-sort aanroept door de booleaanse vergelijkingsfunctie als argument door te geven.

int main()
{
    int i, n = 10, key = 11;
    int arr[10] = { 20, 22, 18, 8, 12, 3, 6, 12, 11, 15 };
    bubble_sort(arr, n, compare);
    cout<<"Sorted Order"<<endl;
    for (int i = 0;i < n;i++) {
        cout << arr[i] << " ";
    }
}

Uitvoer:

Sorted Order
3 6 8 11 12 12 15 18 20 22

Antwoord 7

Het is niet echt een functie, maar het is een gelokaliseerd stukje code. Natuurlijk geeft het niet de code door, alleen het resultaat. Het werkt niet als het wordt doorgegeven aan een gebeurtenisverzender om het op een later tijdstip uit te voeren (omdat het resultaat nu wordt berekend en niet wanneer de gebeurtenis plaatsvindt). Maar het lokaliseert je code wel op één plek als dat alles is wat je probeert te doen.

#include <stdio.h>
int IncMultInt(int a, int b)
{
    a++;
    return a * b;
}
int main(int argc, char *argv[])
{
    int a = 5;
    int b = 7;
    printf("%d * %d = %d\n", a, b, IncMultInt(a, b));
    b = 9;
    // Create some local code with it's own local variable
    printf("%d * %d = %d\n", a, b,  ( { int _a = a+1; _a * b; } ) );
    return 0;
}

Other episodes