2008-08-13 3 views
452

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

+9

Если вы используете функции/массивы в качестве переменных, ВСЕГДА используйте `typedef`. – 2014-01-13 21:09:49

+2

Мы называем это [Указатель функции] (http://en.wikipedia.org/wiki/Function_pointer#Example_in_C) – AminM 2014-04-01 11:11:48

+0

Имя функции должно быть признаком функции. Большинство людей, изучающих C-покрытие qsort, рано или поздно, что делает именно это? – mckenzm 2015-07-03 02:09:17

ответ

583

Декларация

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

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

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

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

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

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

func(print); 

бы назвать func, передавая функцию печати на ней.

Функция Body

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

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

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

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

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

2

Необходимо передать function pointer. Синтаксис немного громоздкий, но он очень мощный, когда вы знакомы с ним.

102

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

typedef void (*functiontype)(); 

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

void dosomething() { } 

functiontype func = &dosomething; 
func(); 

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

typedef int (*functiontype2)(char); 

и использовать его

int dosomethingwithchar(char a) { return 1; } 

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

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

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

гораздо приятнее, чем указано выше.

40

С C++ 11 вы можете использовать functional library, чтобы сделать это в сжатом и общем виде. Синтаксис, например,

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

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

#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(); 
} 
Смежные вопросы