Чтобы модифицировать поведение. Вы передаете в качестве параметра - что делать. Вместо того, чтобы писать отдельно несколько функций, отличающихся лишь маленькой частью, вы пишите лишь одну функцию, где эта маленькая различная часть - вынесена в передаваемую функцию.
Иногда вообще по-другому не сделать. Например, очередь задач. Вот надо вам чтобы в одном потоке выполнялась куча маленьких функций. Тут единственный сопособ - это функцию сохранить в переменную, засунуть в какую-то очередь и потом, когда станет нечего делать, достать ее оттуда и выполнить.
Или у вас вопрос, почему указатель? Ну ведь фунция - это огромный кусок кода в памяти. Логично же ее передавать как указатель, как и массивы, например. Но тут есть еще и низкоуровневая проблема - в процессоре есть защита от исполнения данных. Без дополнительных танцев с бубном, вы никак данные не выполните, даже если там записан корректный машинный код. Поэтому все функции записаны в read-only секции памяти, специально помеченной, как разрешенная к исполнению. Поэтому единственный сопособ как-то эти данные куда-то передать - это указатель туда. Сами данные-то не перемещаемые.