Jak przekazać funkcję jako parametr w C?

Chcę utworzyć funkcję, która wykonuje funkcję przekazaną przez parametr na zbiorze danych. Jak przekazać funkcję jako parametr w C?

Author: gsamaras, 2008-08-13

5 answers

Deklaracja

Prototyp funkcji przyjmującej parametr funkcji wygląda następująco:

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

Oznacza to, że parametr f będzie wskaźnikiem do funkcji, która ma typ zwracania void i która przyjmuje pojedynczy parametr int. Poniższa funkcja (print) jest przykładem funkcji, która może być przekazana do func jako parametr, ponieważ jest typem właściwym:

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

Wywołanie Funkcji

Kiedy wywołanie funkcji z parametrem funkcji, przekazywana wartość musi być wskaźnikiem do funkcji. W tym celu użyj nazwy funkcji (bez nawiasów):

func(print);

Wywoła func, przekazując do niego funkcję print.

Function Body

Jak w przypadku każdego parametru, func może teraz użyć nazwy parametru w ciele funkcji, aby uzyskać dostęp do wartości parametru. Załóżmy, że func zastosuje funkcję przekazaną liczbom 0-4. Zastanów się najpierw, co pętla wygląda tak, jakby wywoływała print bezpośrednio:

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

Ponieważ deklaracja parametru func mówi, że f jest nazwą wskaźnika do pożądanej funkcji, pamiętamy najpierw, że jeśli f jest wskaźnikiem, to *f jest rzeczą, na którą f wskazuje (tzn. funkcja print w tym przypadku). W rezultacie po prostu zamień każde wystąpienie print w powyższej pętli na *f:

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

Z http://math.hws.edu/bridgeman/courses/331/f05/handouts/c-c++-notes.html

 619
Author: Niyaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-24 01:59:51

To pytanie ma już odpowiedź na definiowanie wskaźników funkcji, jednak mogą one być bardzo niechlujne, zwłaszcza jeśli masz zamiar przekazywać je po swojej aplikacji. Aby uniknąć tego nieprzyjemności polecam wpisanie wskaźnika funkcji w coś bardziej czytelnego. Na przykład.

typedef void (*functiontype)();

Deklaruje funkcję, która zwraca void i nie pobiera argumentów. Aby utworzyć wskaźnik funkcji do tego typu można teraz wykonać:

void dosomething() { }

functiontype func = &dosomething;
func();

Dla funkcji, która zwraca int i bierze znak, który byś zrobił

typedef int (*functiontype2)(char);

I używać go

int dosomethingwithchar(char a) { return 1; }

functiontype2 func2 = &dosomethingwithchar
int result = func2('a');

Istnieją biblioteki, które mogą pomóc w przekształcaniu wskaźników funkcji w ładne czytelne typy. Biblioteka boost function jest świetna i warta wysiłku!

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

Jest o wiele ładniejszy niż wyżej.

 106
Author: roo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 13:22:06

Od C++11 możesz użyć functional library , aby to zrobić w zwięzły i ogólny sposób. Składnia to np.

std::function<bool (int)>

Gdzie bool jest typem zwracanym funkcji jednopunktowej, której pierwszy argument jest typu int.

Dodałem przykładowy program poniżej:

// 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);
}

Czasami jednak wygodniej jest użyć funkcji szablonu:

// 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);
}
 45
Author: Richard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 14:02:36

Przekazać adres funkcji jako parametru innej funkcji Jak pokazano poniżej

#include <stdio.h>

void print();
void execute(void());

int main()
{
    execute(print); // sends address of print
    return 0;
}

void print()
{
    printf("Hello!");
}

void execute(void f()) // receive address of print
{
    f();
}

Możemy również przekazać funkcję jako parametr za pomocą Wskaźnik funkcji

#include <stdio.h>

void print();
void execute(void (*f)());

int main()
{
    execute(&print); // sends address of print
    return 0;
}

void print()
{
    printf("Hello!");
}

void execute(void (*f)()) // receive address of print
{
    f();
}
 9
Author: Yogeesh H T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-23 13:20:07

Musisz przekazać Wskaźnik funkcji . Składnia jest trochę kłopotliwa, ale jest naprawdę potężna, gdy się z nią zapoznasz.

 2
Author: saint_groceon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-13 02:18:28