Monday, January 2, 2012

Function Pointers

What are function pointers and what is tha main use of them in C ?

This is useful because functions encapsulate behavior. For instance, every time you need a particular behavior such as drawing a line, instead of writing out a bunch of code, all you need to do is call the function. But sometimes you would like to choose different behaviors at different times in essentially the same piece of code

Uses:
They are used to implement generic functions like qsort(), callbacks, state machines and anywhere else run time binding of a function is required.

Function pointers always point to a function having a specific signature. Thus, all functions used with the same function pointer must have the same parameters and return type

Example Uses of Function Pointers

Functions as Arguments to Other Functions

If you were to write a sort routine, you might want to allow the function's caller to choose the order in which the data is sorted; some programmers might need to sort the data in ascending order, others might prefer descending order while still others may want something similar to but not quite like one of those choices. One way to let your user specify what to do is to provide a flag as an argument to the function, but this is inflexible; the sort function allows only a fixed set of comparison types (e.g., ascending and descending).

A much nicer way of allowing the user to choose how to sort the data is simply to let the user pass in a function to the sort function. This function might take two pieces of data and perform a comparison on them. We'll look at the syntax for this in a bit.

Callback Functions

Another use for function pointers is setting up "listener" or "callback" functions that are invoked when a particular event happens. The function is called, and this notifies your code that something of interest has taken place.

Why would you ever write code with callback functions? You often see it when writing code using someone's library. One example is when you're writing code for a graphical user interface (GUI). Most of the time, the user will interact with a loop that allows the mouse pointer to move and that redraws the interface. Sometimes, however, the user will click on a button or enter text into a field. These operations are "events" that may require a response that your program needs to handle. How can your code know what's happening? Using Callback functions! The user's click should cause the interface to call a function that you wrote to handle the event.

To get a sense for when you might do this, consider what might happen if you were using a GUI library that had a "create_button" function. It might take the location where a button should appear on the screen, the text of the button, and a function to call when the button is clicked. Assuming for the moment that C (and C++) had a generic "function pointer" type called function, this might look like this:
void create_button( int x, int y, const char *text, function callback_func );
Whenever the button is clicked, callback_func will be invoked. Exactly what callback_func does depends on the button; this is why allowing the create_button function to take a function pointer is useful.
Using a function Pointer:

#include <stdio.h>
void my_int_func(int x)
{
    printf( "%d\n", x );
}


int main()
{
    void (*foo)(int);
    foo = &my_int_func;

    /* call my_int_func (note that you do not need to write (*foo)(2) ) */
    foo( 2 );
    /* but if you want to, you may */
    (*foo)( 2 );

    return 0;
}


Useful Links:-
http://www.cprogramming.com/tutorial/function-pointers.html
http://www.newty.de/fpt/callback.html
http://c-faq.com/~scs/cclass/int/sx10b.html
http://blog.robbychen.com/2011/02/08/function-pointers-usage/
http://en.wikipedia.org/wiki/Function_pointer

2 comments:

  1. They are used to implement generic
    functions like qsort(), callbacks, state machines and anywhere else where run
    time binding of a function is required.

    ReplyDelete
  2. 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; }


    // Solution with a switch-statement - //specifies which operation to execute
    void Switch(float a, float b, char opCode)
    {
    float result;

    // execute operation
    switch(opCode)
    {
    case '+' : result = Plus (a, b); break;
    case '-' : result = Minus (a, b); break;
    case '*' : result = Multiply (a, b); break;
    case '/' : result = Divide (a, b); break;
    }

    cout << "Switch: 2+5=" << result << endl; // display result
    }


    // Solution with a function pointer - is a function pointer and points to
    // a function which takes two floats and returns a float. The function pointer
    // "specifies" which operation shall be executed.

    void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
    {
    float result = pt2Func(a, b); // call using function pointer

    cout << "Switch replaced by function pointer: 2-5="; // display result
    cout << result << endl;
    }


    // Execute example code
    void Replace_A_Switch()
    {
    cout << endl << "Executing function 'Replace_A_Switch'" << endl;

    Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
    Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
    }

    ReplyDelete