node_t* func(node_t* n, int f(node_t *))
Есть функция, называемая FUNC, которая принимает два параметра: п, указатель на node_t и п, указатель на функцию, которая принимает указатель node_t и возвращает Int. Функция func возвращает указатель на node_t.
В любом случае, наиболее распространенное использование этого, которое приходит на ум, - это общие алгоритмы.
«Разве вы не можете просто вызвать любую функцию в файле, если она была объявлена?»
Пока функция была объявлена в блоке компиляции, и компоновщик может найти ее во время соединения, это правда. Тем не менее, указатели на функции используются, когда вы хотите иметь возможность решать во время выполнения, какую функцию использовать (или время компиляции, если вы просто хотите использовать общую функцию).
В качестве осязаемого примера рассмотрим qsort:
void qsort (void * base, size_t num, size_t size, int (* comparator) (const void *, const void *));
Теперь рассмотрим это:
typedef struct Student { int id; char* name; }
Student students[10];
//populate students
int sortByName(void* a, void* b)
{
Student* sa = a;
Student* sb = b;
return strcmp(a->name, b->name);
}
int sortById(void* a, void* b)
{
Student* sa = a;
Student* sb = b;
return a->id - b->id;
}
//sort by name:
qsort(students, 10, sizeof(Student), sortByName);
//sort by id:
qsort(students, 10, sizeof(Student), sortById);
Важной частью является то, что сортировка код не должен быть изменен. Реализация сортировки является фактически общей. Это один алгоритм, который работает с разными типами данных, и в этом случае этому обобщению способствует указатель на функцию.
Существует и другое использование указателей функций (немало из них), таких как обратные вызовы или ветвление на основе карты, которая передает что-то функции.