I might’ve missed it in this thread, but particularly in embedded systems pointers to functions, as well as for callbacks, are reasonably common in state machines as an alternative to large case statements.
But you have to be carefull though. I don't use function pointers if they aren't constant (=fixed in flash) otherwise memory corruption can screw up things badly. AFAIK MISRA doesn't allow to use function pointers at all (or at least ones that are not in RAM).
I was uhming and arhing whether to include "security" in my list of caveats but didn't want to muddy the waters.
One case I have used mutable function pointers is in an interrupt driven software slave I2C on a very low end device, without either hardware I2C or vectored interrupts, in order to gain sufficiently fast response. It was faster than a bunch of nested if-then-else and case statements, and the difference between it working and not working in this case.
It's just one of the key skills of engineering, compromising and balancing between different criteria and requirements. On the one I cited, it was a very price sensitive application, so much so the cost of a device with hardware I2C would have made it unviable!
In general, the default position for an FSM these day is a case statement, but I don't think it's too much to ask any reasonably proficient C programmer to be able to deal with function pointers put in there for the right reasons.