Указатели функций


Помните указатели? Мы использовали их, чтобы указать на массив символов, а затем сделать из них строку. Затем все стало интереснее, когда мы узнали, как управлять этими указателями. Теперь пришло время сделать что-то еще более интересное с указателями, используя их для указания и вызова функций.

Зачем указывать на функцию?

Первый вопрос, который может прийти вам в голову, - зачем нам использовать указатели для вызова функции, если мы можем просто вызвать функцию по ее имени: - это отличный вопрос! Теперь представьте функцию, в которой вам нужно отсортировать массив. Иногда вы хотите расположить элементы массива в порядке возрастания или убывания. Как бы вы выбрали? Указатели на функции!function();sort

Синтаксис указателя функции

void (*pf)(int);

Я согласен. Это определенно очень сложно, по крайней мере, вы можете подумать. Давайте перечитаем этот код и попробуем разобраться в нем по пунктам. Прочтите это наизнанку. *pfуказатель на функцию. void- тип возвращаемого значения этой функции и, наконец int, тип аргумента этой функции. Понятно? Хороший.

Вставим указатели в указатель функции и попробуем прочитать его еще раз:

char* (*pf)(int*)

Опять же: 1. *pf- указатель на функцию. 2. - тип возвращаемого значения этой функции. 3. тип аргумента.char*int*

Ладно с теорией. Давайте запачкаем руки реальным кодом. См. Этот пример:

#include <stdio.h>
void someFunction(int arg)
{
    printf("This is someFunction being called and arg is: %d\n", arg);
    printf("Whoops leaving the function now!\n");
}

main()
{
    void (*pf)(int);
    pf = &someFunction;
    printf("We're about to call someFunction() using a pointer!\n");
    (pf)(5);
    printf("Wow that was cool. Back to main now!\n\n");
}

Помните, о чем мы говорили ранее? Мы можем сделать с ним то же самое. Вместо того, чтобы упорядочивать набор по возрастанию, мы можем сделать обратное, используя нашу собственную функцию сравнения следующим образом:sort()

#include <stdio.h>
#include <stdlib.h> //for qsort()

int compare(const void* left, const void* right)
{
    return (*(int*)right - *(int*)left);
    // go back to ref if this seems complicated: http://www.cplusplus.com/reference/cstdlib/qsort/
}
main()
{
    int (*cmp) (const void* , const void*);
    cmp = &compare;

    int iarray[] = {1,2,3,4,5,6,7,8,9};
    qsort(iarray, sizeof(iarray)/sizeof(*iarray), sizeof(*iarray), cmp);

    int c = 0;
    while (c < sizeof(iarray)/sizeof(*iarray))
    {
        printf("%d \t", iarray[c]);
        c++;
    }
}

Вспомним еще раз. Почему мы используем указатели на функции? 1. Разрешить программистам использовать библиотеки для разных целей -> «Гибкость»

Упражнение

Завершите массив указателей на функции и вызовите каждую функцию, используя ее указатель из массива. Массив указателей на функции? Да, ты можешь это сделать!