Указатель на функцию в C — переменная, в которой хранится адрес функции, позволяющий динамически выбирать, какую функцию вызвать. Обычное объявление указателя на функцию:
// Указатель на функцию, принимающую int и возвращающую int int (*f_ptr)(int);
Для массива указателей:
int func1(int x) { return x + 1; } int func2(int x) { return x * 2; } int (*f_arr[2])(int) = { func1, func2 }; int result = f_arr[1](10); // вернет 20
Можно ли с помощью указателя на функцию вызвать функцию с другой сигнатурой?
Частый неверный ответ: «Да, если использовать приведение типа».
Правильный ответ: Технически это возможно из-за динамической природы указателей, но такое действие приводит к runtime-багам и непредсказуемому поведению, т. к. вызываются функции с разными соглашениями о вызове и компоновке аргументов.
Пример:
void funcA(int x) { printf("A: %d ", x); } void funcB(float y) { printf("B: %f ", y); } void (*fptr)(int) = (void (*)(int)) funcB; fptr(5); // ОШИБКА: будут переданы неверные данные
История
История
История
В firmware не проверяли результат смены указателей на функции. Недостаточная инициализация массива обработчиков приводила к вызову нулевого указателя (NULL), после чего устройство зависало без уведомления пользователя.