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

c function pointers syntax parameters

470906 просмотра

7 ответа

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

Автор: andrewrk Источник Размещён: 17.05.2019 02:45

Ответы (7)


657 плюса

Решение

декларация

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

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

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

Автор: Niyaz Размещён: 13.08.2008 02:22

115 плюса

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

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<int (char a)> functiontype2;

это намного приятнее, чем выше.

Автор: roo Размещён: 13.08.2008 02:34

54 плюса

Начиная с 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);
}
Автор: Richard Размещён: 20.07.2015 04:24

13 плюса

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

#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();
}
Автор: Yogeesh H T Размещён: 23.11.2015 12:07

3 плюса

Вам нужно передать указатель на функцию . Синтаксис немного громоздкий, но он становится действительно мощным, когда вы с ним познакомитесь.

Автор: saint_groceon Размещён: 13.08.2008 02:18

1 плюс

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

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

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

void foo(int (*bar)(int, int));
Автор: doppelheathen Размещён: 27.11.2018 03:42

0 плюса

На самом деле это не функция, а локализованный фрагмент кода. Конечно, он не передает код только результат. Он не будет работать, если он будет передан диспетчеру событий для запуска в более позднее время (так как результат рассчитывается сейчас, а не когда происходит событие). Но он локализует ваш код в одном месте, если это все, что вы пытаетесь сделать.

#include <stdio.h>

int IncMultInt(int a, int b)
{
    a++;
    return a * b;
}

int main(int argc, char *argv[])

{
    int a = 5;
    int b = 7;

    printf("%d * %d = %d\n", a, b, IncMultInt(a, b));

    b = 9;

    // Create some local code with it's own local variable
    printf("%d * %d = %d\n", a, b,  ( { int _a = a+1; _a * b; } ) );

    return 0;
}
Автор: Walter Размещён: 15.03.2019 02:46
32x32