Как вызвать функцию, используя указатель на функцию? - PullRequest
29 голосов
/ 23 декабря 2009

Предположим, у меня есть эти три функции:

bool A();
bool B();
bool C();

Как вызвать одну из этих функций условно с помощью указателя функции и как объявить указатель функции?

Ответы [ 16 ]

35 голосов
/ 23 декабря 2009

Вы можете сделать следующее: Предположим, у вас есть следующие функции A, B и C:

bool A()
{
   .....
}

bool B()
{
   .....
}

bool C()
{

 .....
}

Теперь о какой-то другой функции, скажем по главной:

int main()
{
  bool (*choice) ();

  // now if there is if-else statement for making "choice" to 
  // point at a particular function then proceed as following

  if ( x == 1 )
   choice = A;

  else if ( x == 2 )
   choice = B;


  else
   choice = C;

if(choice())
 printf("Success\n");

else
 printf("Failure\n");

.........
  .........
  }

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

20 голосов
/ 23 декабря 2009

Объявите указатель вашей функции следующим образом:

bool (*f)();
f = A;
f();
14 голосов
/ 23 декабря 2009

Я думаю, что на ваш вопрос уже был получен более чем адекватный ответ, но, возможно, было бы полезно явно указать, что дан указатель на функцию

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

два звонка

pf(1, 0);
(*pf)(1, 0);

абсолютно эквивалентны во всех отношениях по определению. Выбор, который использовать, зависит от вас, хотя это хорошая идея, чтобы быть последовательным. Долгое время я предпочитал (*pf)(1, 0), потому что мне казалось, что он лучше отражает тип pf, однако в последние несколько лет я перешел на pf(1, 0).

14 голосов
/ 23 декабря 2009

изначально определяет массив указателей на функции, который принимает void и возвращает void. Предполагая, что ваша функция принимает пустоту и возвращает пустоту.

typedef void (*func_ptr)(void);

Теперь вы можете использовать это для создания переменных указателей на функции таких функций. как ниже:

func_ptr array_of_fun_ptr[3];

теперь сохраните адрес ваших функций в трех переменных.

array_of_fun_ptr[0]= &A;
array_of_fun_ptr[1]= &B;
array_of_fun_ptr[2]= &C;

теперь вы можете вызывать эти функции, используя указатели функций, как показано ниже:

some_a=(*(array_of_fun_ptr[0]))();
some_b=(*(array_of_fun_ptr[1]))();
some_c=(*(array_of_fun_ptr[2]))();
6 голосов
/ 23 декабря 2009

Вы можете объявить указатель функции следующим образом:

bool (funptr*)();

Что говорит о том, что мы объявляем указатель на функцию, которая ничего не берет и возвращает bool.

Следующее назначение:

funptr = A;

Для вызова функции с помощью указателя функции:

funptr();
4 голосов
/ 23 декабря 2009
bool (*FuncPtr)()

FuncPtr = A;
FuncPtr();

Если вы хотите вызвать одну из этих функций условно, вам следует рассмотреть возможность использования массива указателей на функции .В этом случае у вас будет 3 элемента, указывающих на A, B и C, и вы вызовете один из них в зависимости от индекса массива, например funcArray0 для A.

2 голосов
/ 11 сентября 2012

Лучший способ прочитать это «Правило по часовой стрелке / спираль»

Дэвид Андерсон

http://c -faq.com / Децл / spiral.anderson.html

2 голосов
/ 23 декабря 2009

Обратите внимание, что когда вы говорите:

bool (*a)();

вы объявляете a типа «указатель на функцию, возвращающую bool и принимающую неопределенное количество параметров». Предполагая, что bool определено (возможно, вы используете C99 и включили stdbool.h, или это может быть typedef), это может или не может быть тем, что вы хотите.

Проблема здесь в том, что компилятор не может проверить, присвоено ли a правильное значение. Та же проблема существует с вашими объявлениями функций. A(), B() и C() все объявлены как функции «возвращающие bool и принимающие неопределенное количество параметров».

Чтобы увидеть, какие проблемы могут возникнуть, давайте напишем программу:

#include <stdio.h>

int test_zero(void)
{
    return 42;
}

static int test_one(char *data)
{
    return printf("%s\n", data);
}

int main(void)
{
    /* a is of type "pointer to function returning int
       and taking unspecified number of parameters */
    int (*a)();

    /* b is of type "pointer to function returning int
       and taking no parameters */
    int (*b)(void);

    /* This is OK */
    a = test_zero;
    printf("a: %d\n", a());

    a = test_one; /* OK, since compiler doesn't check the parameters */
    printf("a: %d\n", a()); /* oops, wrong number of args */

    /* This is OK too */
    b = test_zero;
    printf("b: %d\n", b());

    /* The compiler now does type checking, and sees that the
       assignment is wrong, so it can warn us */
    b = test_one;
    printf("b: %d\n", b()); /* Wrong again */

    return 0;
}

Когда я компилирую вышеизложенное с помощью gcc, он говорит:

предупреждение: присвоение из несовместимого типа указателя

для строки b = test_one;, что хорошо. Нет предупреждения для соответствующего присвоения a.

Итак, вы должны объявить свои функции как:

bool A(void);
bool B(void);
bool C(void);

И тогда переменная для хранения функции должна быть объявлена ​​как:

bool (*choice)(void);
2 голосов
/ 23 декабря 2009
bool (*fptr)();

int main(void)
{
  ...
  ...
  printf("Enter your choice");
  scanf("%d",&a);
  switch(a)
{
  case 0:
         fptr = A;
         break;
  case 1:
         fptr = B;
         break;
  case 2:
         fptr = C;
         break;
  case 3:
          break;
}
(*fptr)();
return 0;
}

ваш выбор хранится в; Затем, соответственно, функции назначаются в указателе функции. Наконец, в зависимости от вашего выбора вызывается та же самая функция для возврата желаемого результата.

1 голос
/ 19 декабря 2016

Если вам нужна помощь со сложными определениями, например:

double (*(*pf)())[3][4];

Взгляните на мое правое лево-правило здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...