Wednesday, November 03, 2004

Function Pointers demystified

A TO THE POINT EXPLANATION OF POINTERS TO FUNCTIONS OR FUNCTION POINTERS
-- Nishant Agarwal , nishant@purecode.us
The basic idea is that functions too are nothing but addresses. A function may be
called 100 times, but each time the same function is called, its because view the
function as an service requested from that address.
So, this gives the idea that functions too can be passed as arguments to functions,
and used as rvalues, just as addresses of variables or ADTs can.
A good example of this is the C qsort function.
int qsort (ary, N, sizeofeachelement, comparator)
Here, ary is the address of the starting block of memory which contains your
array or collection, N is the length of the collection, the third argument is the
size of each individual entity in the collection, and the fourth is the address of
the function which compares two entities of the collection.
so now, if your function is:
int comparator( Object a, Object b) , then in order to use this function in the above
qsort call, you would just write the name of the function as the fourth argument. What
you are doing is just passing the address of the function, just like you pass the
address of the first argument or any address.
The fun begins when you want to incorporate polymorphism in this idea. You dont want
to bind this call at compile time. So, declare a function pointer which can hold the
address of such a function, just like you would declare an int* p to hold the address
of an integer.
int (*pf) (int a, int b);
this is the function pointer which points to a function which can return an int
and takes the two arguments specified.
Now, suppose you have a comparator function which wants to sort in ascending order,
and one comparator which wants to sort in descending order.
//ascending
int comparator1 (int a, int b) {
if (a == b) return 0;
return a > b ? a : b;
}
//descending
int comparator2 (int a, int b) {
if (a==b) return 0;
return a > b ? b : a;
}
now, you got an array , a[20] of twenty integers. You want to sort in ascending order,
so you would call qsort, but first assign the correct function to your comparator
pointer function:
pf = comparator1;
qsort (a, 20, sizeof(a[0]), pf);
for descending order:
pf = comparator2;
qsort(a, 20, sizeof(a[0]), pf);
voila!! now you got run-time polymorphism akin to virtual functions in C
( do we really need C++ hmmmm).
A further point to note is that you can generalize the pointer to function definitions
even further by using the void * castings.
void* (*pf) (void* a, void* b);
Can this point to compartor 1 and comparator 2? I leave this to you to find out.
Also, what will this do:
int (*pf)[ ] (int a, int b);

0 Comments:

Post a Comment

<< Home