As we have learn about function pointer from basic to advance level in article Function Pointers in C/C++, now its time to learn What are practical uses of function pointers in c ?
There are many use of function pointer but all they are summing around callback construct, so here i write two use cases for function pointers upon callback construction:
=> Implement Callback functions – used for Event Handlers, parser specialization, comparator function passing.
=> Dynamically function calling(One kind of callback use case) – Create plugins and extension, Enable-Disables some features upon certain events, creating Finite State Machines(FSM), etc
What is a Callback function?
In simple terms, a Callback function is one that is not called explicitly by the programmer. Instead, there is some mechanism that continually waits for events to occur, and it will call selected functions in response to particular events.
Thus, callbacks allow the user of a function to fine-tune it at runtime(Dynamically function calling).
Practical scenario of Callback
Error Signaling in UNIX – A Unix program, for example, might not want to terminate immediately when it receives SIGTERM, to make sure things get taken care of, it would register the cleanup function as a callback.
Typing certain key combinations at the controlling terminal of a running process in UNIX causes the system to send certain signals:
- Ctrl+C sends an INT signal (SIGINT); by default, this causes the process to terminate.
- Ctrl+Z sends a TSTP signal (SIGTSTP); by default, this causes the process to suspend execution.
- Ctrl+\ sends a QUIT signal (SIGQUIT); by default, this causes the process to terminate and dump core.
There are more than 30 signals which are generated based on certain situation arise. Here is small example of SIGINT handler to clarify things more.
/* signal example */ #include <stdio.h> #include <signal.h> /* signal, raise, sig_atomic_t */ void my_handler (int param) { printf (" Signal raised by pressing Ctrl+C.\n"); } int main () { void (*prev_handler)(int); prev_handler = signal (SIGINT, my_handler); while(1) { //Do some stuff, Wait to signal arise } return 0; }
Finite State Machines(FSM)
Finite State Machinesm or simply state machine where the elements of (multi-dimensional) arrays indicate the routine that processes/handles the next state.
Enabling features and disabling of features can be done using function pointers. You may have features that you wish to enable or disable that do similar yet distinct things. Instead of populating and cluttering your code with if-else or switch constructs testing variables, you can code it so that it uses a function pointer, and then you can enable/disable features by changing/assigning the function pointer. If you add new variants, you don’t have to track down all your if-else or switch cases (and risk missing one); instead you just update your function pointer to enable the new feature, or disable the old one.
Reducing code cluster
/* Finite State Machine FSM */ switch(a) { case 0: func0(); break; case 1: func1(); break; case 2: func2(); break; case 3: func3(); break; default: funcX(); break; }
Can be simplified to …
/* This declaration may be off a little, but I am after the essence of the idea */ void (*funcArray)(void)[] = {func0, func1, func2, func3, funcX}; ... appropriate bounds checking on 'a' ... funcArray[a]();
Sources
- http://en.wikipedia.org/wiki/Callback_%28computer_programming%29
- http://stackoverflow.com/questions/6807376/call-back-routine
- http://stackoverflow.com/questions/8975208/whats-the-use-of-function-pointers