Sunday, September 23, 2012

PASSING FUNCTION AS ARGUMENT IN C/C++


PASSING FUNCTIONS AS ARGUMENT

DISCLAIMER: Though program(s) mentioned here is a working program and also, I have tried my best to make this content error free, but still I do not claim that every concept mentioned here is correct. Therefore, content available here is not meant for primary source of learning.

Introduction
We have passed variable, constants, structure variables to a function as argument. But have you ever tried or thought to pass a function as an argument to another function. If not, then let us do it together. At first sight it may appear a bit confusing to you but trust me it is as simple as writing “int main()” .

Story behind this story(blog):
Well, I want to share with you that how I thought to learn this concept. Once I was programming a graphical Tic Tac Toe game in C++ using  SDL library, in that I created 3 buttons to perform different actions like “New Game”, ”Exit”, ”High Score”. Therefore, it is obvious that these buttons will perform different tasks, but for this I have to rewrite the same code 3 times to create and display button that will perform its defined task. But, I was feeling too lazy for that, so I thought that my work would get easier if I could somehow pass function as an argument to a function, By doing this, I can simply write common code for button just once and can pass different functions that perform their defined tasks like start a new game, show high score etc. So, I searched on Internet, got some hint, and completed my program.

Now let’s begin Learning………….

I believe that you have some knowledge of pointers in C/C++.

REMEMBER: FUNCTION NAME ACTUALLY REFERS TO THE ADDRESS OF THE FUNCTION.

If you had read and understood above line then you must have guessed that we will need pointers to deal with memory addresses.
(We will see a complete working program later in this blog.)

A.      HOW TO DECLARE POINTERS TO FUNCTION:

return_type (*pointer_name)(parameter_list);

Here, * tells that we declared a pointer to function.

NOTE: If the function to be pointed does not take any arguments, then you have to place () or (void) in place of parameter list.
Declaration of Function
Above image clearly explains what these data types and names means.

Please Note: Parenthesis of (*compute) i.e. ‘(‘ and ‘)’ are compulsory(as per my knowledge) to remove ambiguity for compiler, I mean If you do not enclose *compute in parenthesis then compiler will get confused that * is used with void and your declaration will be treated as void * compute(int,int), i.e.  a function named compute taking two arguments of int type and returning pointer of void type.

Q. Create a pointer for char sayHello(int,char) function.
Ans. char (*fp)(int,char);

B.      INITIALIZING FUNCTION POINTERS WITH A FUNCTION

                function_pointer_name=function_name;

EXAMPLE             Let a function sum:
                                void sum(int a, int b)
                                {
                                                cout<<”Sum =”<<a+b;
                                }
                To initialize compute(created earlier) we will write
                                compute=sum;

NOTE: do not use parenthesis with sum( i.e do not write sum()).

C.      CALLING FUNCTIONS USING FUNCTION POINTERS

                function_pointer_name(arguments);

EXAMPLE             to call sum function using compute function pointer write
                                      compute(5,2);
                or, compute(x,y); //where x,y may be a variable or a constant
See this(screen scrap of code):
Calling Function

D.      WRITING FUNCTIONS THAT TAKE FUNCTION AS ARGUMENT

Functions taking functions as argument are nothing but normal functions which contain one or more pointers to function.
Function that takes function as argument
EXAMPLE
See that the function takeFunction is written in usual way except that there is a function pointer in its parameter list (see void (*fp) (int,int) above).
Please note that I have used two more parameters a, b of int type that are used as arguments while calling the function (see fp(a,b);), Its was not mandatory to include int a, int b in parameter list but still I included it for convenience. I might have used the following definition which is also true, but you can see that each time the function is called with same data (i.e. 5, 2) which is probably of no use (see below).

void takeFunction(void (*fp) (int,int))// is not much reliable
{
     fp(5,2);
}

E.       CALLING FUNCTIONS THAT TAKE FUNCTION AS ARGUMENT

Now, it’s time to call the function (ex. takeFunction defined above).

See example below to understand
                takeFunction (sum, 5, 2);

What I have done is just passed the sum function (defined in section B) to this takeFunction function as argument for its fp function pointer , other arguments 5, 2 are passed in usual way as you do normally.
NOTE: do not use parenthesis with sum( i.e sum()) when passing it as argument.

F.       COMPLETE C++ PROGRAM THAT USES ABOVE CONCEPTS

#include<iostream.h>
#include<conio.h>

void sum(int a, int b)
{
     cout<<"\nSum ="<<a+b;
}
void diff(int a, int b)
{
     cout<<"\nDifference ="<<a-b;
}

void takeFunction(void (*fp) (int,int),int a, int b)
{
     fp(a,b);
}

int main()
{
     clrscr();
     void (*compute)(int,int);

     compute=sum;
     compute(5,2);

     compute=diff;
     compute(5,2);

     takeFunction(sum,2,3);
     takeFunction(diff,2,3);

     getch();
     return 0;
}

NO SEE HOW DECLARATION OF VARIABLE POINTER IS DIFFERENT FROM FUCNTION POINTER
see the difference


THANKS!!!!!!!!!!!!!!!!!