GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 09-May-2008, 06:09
KK2202 KK2202 is offline
New Member
 
Join Date: Feb 2008
Posts: 6
KK2202 is on a distinguished road

Use of function pointers


Hi all,

I found in a tutorial on function pointers that apart from being used for Callback functions, the function pointers can also be used to replace switch statments. Please find below the example code for the same :

CPP / C++ / C Code:
//------------------------------------------------------------------------------------
// 1.2 Introductory Example or How to Replace a Switch-Statement
// Task: Perform one of the four basic arithmetic operations specified by the
//       characters '+', '-', '*' or '/'.


// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
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 - <opCode> 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 - <pt2Func> 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);
}

I dont find any use of function pointers or even the need for switch statements here. A direct call to the function plus could be made in the function Replace_A_Switch instead of calling Switch. Hence, i could not appreciate the use of function pointers in this context.

Can anyone explain me better the use of function pointers other than for call back functions ?

Hoping to get a positive resoponse.

Thanks & Regards,
KK2202
Last edited by LuciWiz : 09-May-2008 at 08:08. Reason: Please insert your C/C++ code between [cpp] & [/cpp] tags
  #2  
Old 09-May-2008, 09:01
L7Sqr L7Sqr is offline
Member
 
Join Date: Jul 2005
Location: constant limbo
Posts: 234
L7Sqr is a jewel in the roughL7Sqr is a jewel in the rough

Re: Use of function pointers


Consider the following:
CPP / C++ / C Code:
#include <stdio.h>

int dummy () { return 42; }

typedef int (*fun_ptr)();

int main () {

        int x, y = dummy ();
        fun_ptr call = &dummy;
        x = call ();

        printf ("x : y  -> %d : %d\n", x, y);
        return 0;
}
And then
Code:
GNU gdb Red Hat Linux (6.3.0.0-1.153.el4_6.2rh) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) break main Breakpoint 1 at 0x804838e: file f.c, line 9. (gdb) r Starting program: a.out Breakpoint 1, main () at f.c:9 9 int x, y = dummy (); (gdb) ptype fun_ptr type = int (*)() (gdb) ptype &dummy type = int (*)() (gdb) ptype &main type = int (*)() (gdb)

I realize that you may still consider this 'callbacks' but it would be pretty hard to write a program that did anything useful without having this functionality. The fact that you can invoke code at another location by essentially aliasing that block with a name instead of copying all into main (which itself has the int (*)() properties; ponder that) is pretty stinkin' nice.
  #3  
Old 10-May-2008, 01:02
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,197
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Use of function pointers


Quote:
Originally Posted by KK2202
I dont find any ...
At the beginning, sometimes people describe features of a language with contrived examples. I, too, am not in any way impressed by useless stuff put there just for the heck of it.

I personally feel that use of things like pointers to functions should be discussed after there has been enough exposition that the student can get a flavor of their significance by seeing a real, practical example.

For example, the standard C library funciton qsort is quite flexible with the things that It can sort. In order to sort stuff, you have to tell it something about the stuff (places in memory where the items are located and how much memory the items take up).

You also have to feed qsort the address of a function that you are going to use to compare data items. That is, you have a pointer to the function. For simple things like arrays, the comparison function just returns a plus or minus value, depending on whether the thing pointed to by the first argument is greater or less than the second item.

Depending on the logic inside the comparison function, the array can be sorted in ascending order or descending order.

CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>

void printarray(int *, int );

/* 
 * The following says that compar1 is a function that returns
 * an int. It has two parameters, which are void pointers
 */
int (compar1)(const void *, const void *);

/* 
 * The following says that compar2 is a function that returns
 * an int. It has two parameters, which are void pointers
 */
int (compar2)(const void *, const void *);

/* 
 * The fourth parameter to qsort is a pointer to a function.
 * The function has two parameters which are void pointers, 
 * and the function returns an int.
 *
 * When you use a function name by itself (no parentheses)
 * it is taken to be a pointer whose value is the address of
 * the function.
 *
 * When we call qsort with compar1 it sorts in ascending order.
 * When we call qsort with compar2 it sorts in descending order.
 */

int main()
{
    int x[5] = {3,1,4,2,5};

    printf("Initial array elements  : ");
    printarray(x, 5);

    qsort(x, 5, sizeof(int), compar1);
    printf("After qsort with compar1: ");
    printarray(x, 5);

    qsort(x, 5, sizeof(int), compar2);
    printf("After qsort with compar2: ");
    printarray(x, 5);

    return 0;
}

void printarray(int *x, int siz)
{
    int i;
    for (i = 0; i < siz; i++) {
        printf("%3d ", x[i]);
    }
    printf("\n");
}

/* 
 * compar1 returns a negative value if the first
 * item is less than the second.
 *
 * It returns a positive value if the second is
 * smaller.
 *
 * It returns zero if the two are equal.
 */
int compar1(const void *p1, const void *p2)
{
    const int * ip1 = p1;
    const int * ip2 = p2;
    return (*ip1 - *ip2);
}

/* 
 * compar2 returns a negative value if the second
 * item is first than the second.
 *
 * It returns a positive value if the first is
 * smaller.
 *
 * It returns zero if the two are equal.
 */
int compar2(const void *p1, const void *p2)
{
    const int * ip1 = p1;
    const int * ip2 = p2;
    return (*ip2 - *ip1);
}



Output
Code:
Initial array elements : 3 1 4 2 5 After qsort with compar1: 1 2 3 4 5 After qsort with compar2: 5 4 3 2 1

So, except for the rather exotic-looking function prototype declarations, it still doesn't look much like an example of the use of pointers to functions. (The fourth argument to qsort is a pointer to function, but we just used the function name rather than a separate variable whose type is pointer to function.)

So, let's go a little further.

A more interesting example might be to have an array of two pointers to functions. One would have a value that the address of compar1, and the other would have a value that is the address of compar2.

Then the program could prompt the user to select whether he/she wanted the sort to be in ascending order or descending order, and the proper pointer would be used to call qsort.
CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>

void printarray(int *, int );
int (compar1)(const void *, const void *);
int (compar2)(const void *, const void *);

int main()
{
    /* fpointer is an array of two pointers to functions
     * Each the functions has an int return type, and
     * has two parameters, which are void pointers
     *
     * The pointer array is initialized with the addresses
     * of the comparison functions for qsort
     */

    int (*fpointer[2])(const void *,const void *) = {
        compar1,
        compar2 
    };
    int x[5] = {3,1,4,2,5};
    int choice;
    printf("Here's the array:\n");
    printarray(x, 5);
    printf("\n");

    printf("Here are the choices:\n");
    printf("  1. Sort in ascending order\n");
    printf("  2. Sort in descendng order\n\n");
    printf("Enter your selection: ");
    if ((scanf("%d", &choice) != 1) || (choice < 1) || (choice > 2)) {
        printf("Invalid.\n");
        return 0;
    }
    qsort(x, 5, sizeof(int), fpointer[choice-1]);
    printf("OK! Here's the result for selection %d:\n", choice);
    printarray(x, 5);

    return 0;
}

void printarray(int *x, int siz)
{
    int i;
    for (i = 0; i < siz; i++) {
        printf("%3d ", x[i]);
    }
    printf("\n");
}

int compar1(const void *p1, const void *p2)
{
    const int * ip1 = p1;
    const int * ip2 = p2;
    return (*ip1 - *ip2);
}

int compar2(const void *p1, const void *p2)
{
    const int * ip1 = p1;
    const int * ip2 = p2;
    return (*ip2 - *ip1);
}
Output:
Code:
Here's the array: 3 1 4 2 5 Here are the choices: 1. Sort in ascending order 2. Sort in descendng order Enter your selection: 1 OK! Here's the result for selection 1: 1 2 3 4 5

You can do Stuff Like That with function ponters.

Regards,

Dave
  #4  
Old 13-May-2008, 22:42
KK2202 KK2202 is offline
New Member
 
Join Date: Feb 2008
Posts: 6
KK2202 is on a distinguished road

Re: Use of function pointers


Thank you very much Dave and l7sqr for taking out time and explaining the stuff with examples.
 
 

Recent GIDBlogOnce again, no time for hobbies by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
run script command on ns2.26 newbie06 Computer Software Forum - Linux 65 19-Aug-2009 08:50
[Tutorial] Function Pointers aaroncohn C++ Forum 4 17-Feb-2006 12:33
[Tutorial] Pointers in C (Part II) Stack Overflow C Programming Language 0 27-Apr-2005 18:36
[Tutorial] Pointers in C (Part I) Stack Overflow C Programming Language 1 08-Apr-2005 19:35

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 08:18.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.