Question Comment passez-vous une fonction en tant que paramètre dans C?


Je veux créer une fonction qui exécute une fonction passée par paramètre sur un ensemble de données. Comment passez-vous une fonction en tant que paramètre dans C?


480
2017-08-13 02:16


origine


Réponses:


Déclaration

Un prototype pour une fonction qui prend un paramètre de fonction ressemble à ceci:

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

Cela indique que le paramètre f sera un pointeur vers une fonction qui a un void type de retour et qui prend un seul int paramètre. La fonction suivante (print) est un exemple de fonction qui pourrait être transmise à func comme paramètre car c'est le type approprié:

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

Appel de fonction

Lors de l'appel d'une fonction avec un paramètre de fonction, la valeur transmise doit être un pointeur sur une fonction. Utilisez le nom de la fonction (sans parenthèses) pour cela:

func(print);

appellerait func, en lui passant la fonction d'impression.

Corps de fonction

Comme avec n'importe quel paramètre, func peut maintenant utiliser le nom du paramètre dans le corps de la fonction pour accéder à la valeur du paramètre. Disons que func appliquera la fonction qui est passée aux nombres 0-4. Considérons, en premier lieu, à quoi ressemblerait la boucle pour appeler directement l'impression:

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

Depuis funcLa déclaration des paramètres dit que f est le nom d'un pointeur sur la fonction souhaitée, nous rappelons d'abord que si f est un pointeur alors *f est la chose qui f pointe vers (c'est-à-dire la fonction print dans ce cas). Par conséquent, il suffit de remplacer chaque occurrence d'impression dans la boucle ci-dessus par *f:

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

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


607
2017-08-13 02:22



Cette question a déjà la réponse pour définir les pointeurs de fonction, mais ils peuvent être très désordonnés, surtout si vous allez les transmettre autour de votre application. Pour éviter ce désagrément, je vous recommande de saisir le pointeur de la fonction dans quelque chose de plus lisible. Par exemple.

typedef void (*functiontype)();

Déclare une fonction qui retourne un vide et ne prend aucun argument. Pour créer un pointeur de fonction sur ce type, vous pouvez maintenant faire:

void dosomething() { }

functiontype func = &dosomething;
func();

Pour une fonction qui retourne un int et prend un caractère que vous feriez

typedef int (*functiontype2)(char);

et de l'utiliser

int dosomethingwithchar(char a) { return 1; }

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

Il existe des bibliothèques qui peuvent aider à transformer les pointeurs de fonctions en types lisibles. le fonction boost la bibliothèque est géniale et vaut bien l'effort!

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

est tellement mieux que ce qui précède.


105
2017-08-13 02:34



Depuis C ++ 11, vous pouvez utiliser le bibliothèque fonctionnelle de le faire de manière succincte et générique. La syntaxe est, par exemple,

std::function<bool (int)>

bool est le type de retour ici d'une fonction à un argument dont le premier argument est de type int.

J'ai inclus un exemple de programme ci-dessous:

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

Parfois, cependant, il est plus pratique d'utiliser une fonction de modèle:

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

41
2017-07-20 16:24



Passer adresse d'une fonction comme paramètre d'une autre fonction comme indiqué ci-dessous

#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();
}

Nous pouvons également passer la fonction en tant que paramètre en utilisant pointeur de fonction

#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();
}

8
2017-11-23 12:07



Vous devez passer un pointeur de fonction. La syntaxe est un peu lourde, mais elle est vraiment puissante une fois que vous vous en êtes familiarisé.


2
2017-08-13 02:18