Поиск по сайту:

Учебник по программированию на C для Linux. Часть 25. Указатели на функции


На этой странице

  1. Указатели функций в языке программирования C
  2. Заключение

До сих пор в этой продолжающейся серии руководств по программированию на C мы обсуждали базовую концепцию указателей, а также довольно много аспектов, связанных с указателями, таких как указатель на массив и массив указателей. Расширяя наше понимание указателей, в этом руководстве мы обсудим концепцию указателей на функции.

Указатели функций в языке программирования C

Точно так же, как у нас есть указатели на переменные, также могут быть указатели на функции. Ниже приведен пример объявления указателя на функцию:

void (*fn_ptr)(int)

Итак, здесь у нас есть указатель на функцию с именем fn_ptr, который может указывать на любую функцию, которая возвращает void и принимает целое число в качестве входных данных. Излишне говорить, что это просто часть объявления - как и любому другому указателю, вам нужно присвоить ему адрес (в данном случае адрес функции), чтобы использовать его.

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

#include <stdio.h>

void print_int(int a)
{
printf("\n The integer value is: %d\n",a);
}

int main()
{
void (*fn_ptr)(int);
fn_ptr = &print_int;
(*fn_ptr)(10);

return 0;
}

Итак, как видите, мы сначала определили функцию print_int, которая принимает целое число и возвращает значение void. Затем в основной функции мы объявили fn_ptr как указатель на функцию, который может указывать на такие функции, как print_int. Затем последовало присвоение адреса функции print_int fn_ptr и, наконец, вызов функции с помощью указателя.

Вот результат:

The integer value is: 10 

Здесь стоит упомянуть, что вы можете еще больше упростить эту программу, избегая & и * в последних двух строках. Ниже приведен модифицированный код:

#include <stdio.h>

void print_int(int a)
{
printf("\n The integer value is: %d\n",a);
}

int main()
{
void (*fn_ptr)(int);
fn_ptr = print_int;
fn_ptr(10);

return 0;

Двигаясь дальше, подобно массиву указателей, вы также можете иметь массив указателей на функции. Например, ниже приведен массив указателей на функции, способный хранить 3 адреса функций.

void (*fn_ptr[3])(int)

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

void print_int1(int a)
{
printf("\n The integer value is: %d\n",a);
}

void print_int2(int a)
{
printf("\n The integer value is: %d\n",a+1);
}

void print_int3(int a)
{
printf("\n The integer value is: %d\n",a+2);
}

int main()
{
void (*fn_ptr[3])(int);

fn_ptr[0] = print_int1;
fn_ptr[1] = print_int2;
fn_ptr[2] = print_int3;

fn_ptr[0](10);
fn_ptr[1](10);
fn_ptr[2](10);

return 0;
}

Вот результат, полученный этим кодом:

The integer value is: 10 

The integer value is: 11

The integer value is: 12

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

void some_random_func(void (*fn_ptr)(int)) 

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

#include <stdio.h>

void another_random_func(int a)
{
printf("\n The integer to entered is: %d\n", a);
}

void some_random_func(void (*fn_ptr)(int))
{
fn_ptr(5);
}


int main()
{
some_random_func(another_random_func);
return 0;
}

Итак, что мы сделали здесь, так это создали функцию, названную some_random_func, которая принимает указатель на функцию на входе. Затем из main мы вызвали some_random_func с адресом другой функции other_random_func в качестве аргумента. Затем с помощью указателя мы успешно вызвали Another_random_func.

Вот результат:

The integer to entered is: 5 

Заключение

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