Я хочу создать функцию, которая выполняет функцию, переданную параметром в наборе данных. Как передать функцию в качестве параметра в C?
Как передать функцию в качестве параметра в C?
Ответ 1
Декларация
Прототип функции, которая принимает параметр функции, выглядит следующим образом:
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. Рассмотрим, во-первых, что цикл будет выглядеть так, чтобы называть печать напрямую:
for ( int ctr = 0 ; ctr < 5 ; ctr++ ) {
print(ctr);
}
Так как объявление параметра func
говорит, что 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
У этого вопроса уже есть ответ для определения указателей функций, однако они могут стать очень грязными, особенно если вы собираетесь передавать их вокруг своего приложения. Чтобы избежать этой неприятности, я бы рекомендовал вам ввести указатель функции во что-то более читаемое. Например.
typedef void (*functiontype)();
Объявляет функцию, которая возвращает void и не принимает аргументов. Чтобы создать указатель на этот тип, вы можете:
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 является отличной и заслуживает внимания!
boost::function<int (char a)> functiontype2;
намного лучше, чем выше.
Ответ 3
С С++ 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);
}
Ответ 4
Передайте адрес функции как параметра в другую функцию, как показано ниже
#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();
}
Ответ 5
Вам нужно передать указатель функции . Синтаксис немного громоздкий, но он действительно мощный, когда вы знакомы с ним.