Я думаю, классическим примером в C является qsort . Цитирую оттуда (и я действительно знаю, что это http://www.cplusplus.com,, так что не очень хороший сайт, но, похоже, это правильно)
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
Функция, которая сравнивает два элемента. Функция должна следовать этому прототипу:
int comparator ( const void * elem1, const void * elem2 );
Функция должна принимать два параметра, которые являются указателями на элементы, приведенные к типу как void *. Эти параметры должны быть возвращены к какому-либо типу данных и сопоставлены.
Возвращаемое значение этой функции должно представлять, считается ли elem1 меньше, равен или больше, чем elem2, возвращая, соответственно, отрицательное значение, ноль или положительное значение.
Другим «классическим» примером является калькулятор (например, см. это , это C ++, но то же самое в C).
У вас есть четыре математические функции, например
float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }
каким-то образом вы выбираете операцию
/* Here there should be an if or a switch/case that selects the right operation */
float (*ptrFunc)(float, float) = Plus;
и вы можете вызвать его позже (по какой-то причине вы не хотите вызывать его напрямую в if/switch
, возможно, потому что вы хотите сделать другие "вещи", "общие" для всех операций, такие как ведение журнала или распечатать результат)
float result = ptrFunc(1.0f, 2.0f);
Еще две вещи, для которых вы можете использовать указатели функций, это обратные вызовы (как написано vine'th
) и виртуальные функции «бедняков» (вы помещаете их в struct
и когда вы создаете struct
(вы знаете, как использование конструктора «бедняги», но это C, поэтому мы будем называть его инициализатором), вы сохраняете там, какие функции будут использоваться этим struct
).