Как передать функцию в качестве параметра в C

c function pointers syntax parameters


Я хочу создать функцию,которая будет выполнять функцию,передаваемую по параметру,на наборе данных.Как передать функцию в качестве параметра в C?




Answer 1 Niyaz


Declaration

Прототип функции,которая принимает параметр функции,выглядит следующим образом:

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

Это означает, что параметр f будет указателем на функцию, которая имеет возвращаемый тип void и принимает единственный параметр int . Следующая функция ( print ) является примером функции, которую можно передать func в качестве параметра, потому что это правильный тип:

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

Вызов функции

При вызове функции с параметром функции передаваемое значение должно быть указателем на функцию.Для этого используется имя функции (без скобок):

func(print);

вызовет func , передав ему функцию печати.

Тело функции

Как и любой параметр, func теперь может использовать имя параметра в теле функции для доступа к значению параметра. Предположим, что func применит переданную функцию к числам 0-4. Сначала рассмотрим, как будет выглядеть цикл при прямом вызове print:

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

Поскольку в объявлении параметра func указано, что f - это имя указателя на желаемую функцию, мы сначала напомним, что если f является указателем, то *f - это то, на что указывает f (то есть функция print в данном случае). В результате просто замените каждое вхождение print в приведенном выше цикле на *f :

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

Source




Answer 2 roo


Этот вопрос уже имеет ответ на определение указателей функции,однако они могут стать очень запутанными,особенно если вы собираетесь передавать их по вашему приложению.Чтобы избежать этой неприятности,я бы порекомендовал напечатать указатель функции во что-нибудь более читабельное.Например.

typedef void (*functiontype)();

Объявляет функцию,которая возвращает пустоту и не принимает аргументов.Создать указатель функции на этот тип теперь можно:

void dosomething() { }

functiontype func = &dosomething;
func();

Для функции,которая возвращает int и принимает char,вы бы сделали

typedef int (*functiontype2)(char);

и пользоваться им

int dosomethingwithchar(char a) { return 1; }

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

Существуют библиотеки, которые могут помочь превратить указатели функций в удобные для чтения типы. Функция повышения великолепна и стоит затраченных усилий!

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

намного приятнее,чем было сказано выше.




Answer 3 Richard


Начиная с C ++ 11 вы можете использовать функциональную библиотеку, чтобы делать это в сжатой и общей форме. Синтаксис, например,

std::function<bool (int)>

где bool - это тип возвращаемого значения функции с одним аргументом, первый аргумент которой имеет тип int .

Ниже я включил пример программы:

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

Иногда,однако,удобнее использовать функцию шаблона:

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



Answer 4 Yogeesh H T


Передайте адрес функции в качестве параметра другой функции, как показано ниже.

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

Также мы можем передать функцию как параметр, используя указатель функции

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



Answer 5 doppelheathen


Функции могут быть «переданы» как указатели на функции, в соответствии с ISO C11 6.7.6.3p8: « Объявление параметра как« тип возвращающей функции »должно быть скорректировано на« указатель на тип, возвращающий функцию » , как в 6.3. .2.1. ". Например, это:

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

эквивалентно этому:

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