How can I use an array of function pointers?

CInitializationFunction Pointers

C Problem Overview


How should I use array of function pointers in C?

How can I initialize them?

C Solutions


Solution 1 - C

You have a good example here (Array of Function pointers), with the syntax detailed.

int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);

int (*p[4]) (int x, int y);

int main(void)
{
  int result;
  int i, j, op;

  p[0] = sum; /* address of sum() */
  p[1] = subtract; /* address of subtract() */
  p[2] = mul; /* address of mul() */
  p[3] = div; /* address of div() */
[...]

To call one of those function pointers:

result = (*p[op]) (i, j); // op being the index of one of the four functions

Solution 2 - C

The above answers may help you but you may also want to know how to use array of function pointers.

void fun1()
{

}

void fun2()
{

}

void fun3()
{

}

void (*func_ptr[3])() = {fun1, fun2, fun3};

main()
{
    int option;
 

    printf("\nEnter function number you want");
    printf("\nYou should not enter other than 0 , 1, 2"); /* because we have only 3 functions */
    scanf("%d",&option);
    
    if((option>=0)&&(option<=2))
    { 
        (*func_ptr[option])();
    }

    return 0;
}

You can only assign the addresses of functions with the same return type and same argument types and no of arguments to a single function pointer array.

You can also pass arguments like below if all the above functions are having the same number of arguments of same type.

  (*func_ptr[option])(argu1);

Note: here in the array the numbering of the function pointers will be starting from 0 same as in general arrays. So in above example fun1 can be called if option=0, fun2 can be called if option=1 and fun3 can be called if option=2.

Solution 3 - C

Here's how you can use it:

###New_Fun.h

#ifndef NEW_FUN_H_
#define NEW_FUN_H_

#include <stdio.h>

typedef int speed;
speed fun(int x);

enum fp {
    f1, f2, f3, f4, f5
};

void F1();
void F2();
void F3();
void F4();
void F5();
#endif

###New_Fun.c

#include "New_Fun.h"

speed fun(int x)
{
    int Vel;
    Vel = x;
    return Vel;
}

void F1()
{
    printf("From F1\n");
}

void F2()
{
    printf("From F2\n");
}

void F3()
{
    printf("From F3\n");
}

void F4()
{
    printf("From F4\n");
}

void F5()
{
    printf("From F5\n");
}

###Main.c

#include <stdio.h>
#include "New_Fun.h"

int main()
{
    int (*F_P)(int y);
    void (*F_A[5])() = { F1, F2, F3, F4, F5 };    // if it is int the pointer incompatible is bound to happen
    int xyz, i;

    printf("Hello Function Pointer!\n");
    F_P = fun;
    xyz = F_P(5);
    printf("The Value is %d\n", xyz);
    //(*F_A[5]) = { F1, F2, F3, F4, F5 };
    for (i = 0; i < 5; i++)
    {
        F_A[i]();
    }
    printf("\n\n");
    F_A[f1]();
    F_A[f2]();
    F_A[f3]();
    F_A[f4]();
    return 0;
}

I hope this helps in understanding Function Pointer.

Solution 4 - C

This "answer" is more of an addendum to VonC's answer; just noting that the syntax can be simplified via a typedef, and aggregate initialization can be used:

typedef int FUNC(int, int);

FUNC sum, subtract, mul, div;
FUNC *p[4] = { sum, subtract, mul, div };

int main(void)
{
    int result;
    int i = 2, j = 3, op = 2;  // 2: mul

    result = p[op](i, j);   // = 6
}

// maybe even in another file
int sum(int a, int b) { return a+b; }
int subtract(int a, int b) { return a-b; }
int mul(int a, int b) { return a*b; }
int div(int a, int b) { return a/b; }

Solution 5 - C

Here's a simpler example of how to do it:

jump_table.c

int func1(int arg)  { return arg + 1; }
int func2(int arg)  { return arg + 2; }
int func3(int arg)  { return arg + 3; }
int func4(int arg)  { return arg + 4; }
int func5(int arg)  { return arg + 5; }
int func6(int arg)  { return arg + 6; }
int func7(int arg)  { return arg + 7; }
int func8(int arg)  { return arg + 8; }
int func9(int arg)  { return arg + 9; }
int func10(int arg) { return arg + 10; }

int (*jump_table[10])(int) = { func1, func2, func3, func4, func5, 
                               func6, func7, func8, func9, func10 };
    
int main(void) {
  int index = 2;
  int argument = 42;
  int result = (*jump_table[index])(argument);
  // result is 45
}

All functions stored in the array must have the same signature. This simply means that they must return the same type (e.g. int) and have the same arguments (a single int in the example above).


In C++, you can do the same with static class methods (but not instance methods). For example you could use MyClass::myStaticMethod in the array above but not MyClass::myInstanceMethod nor instance.myInstanceMethod:

class MyClass {
public:
  static int myStaticMethod(int foo)   { return foo + 17; }
  int        myInstanceMethod(int bar) { return bar + 17; }
}

MyClass instance;

Solution 6 - C

Oh, there are tons of example. Just have a look at anything within glib or gtk. You can see the work of function pointers in work there all the way.

Here e.g the initialization of the gtk_button stuff.


static void
gtk_button_class_init (GtkButtonClass *klass)
{
GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;




gobject_class = G_OBJECT_CLASS (klass);
object_class = (GtkObjectClass*) klass;
widget_class = (GtkWidgetClass*) klass;
container_class = (GtkContainerClass*) klass;




gobject_class->constructor = gtk_button_constructor;
gobject_class->set_property = gtk_button_set_property;
gobject_class->get_property = gtk_button_get_property;


And in gtkobject.h you find the following declarations:


struct _GtkObjectClass
{
GInitiallyUnownedClass parent_class;




/* Non overridable class methods to set and get per class arguments */
void (*set_arg) (GtkObject *object,
GtkArg    *arg,
guint      arg_id);
void (*get_arg) (GtkObject *object,
GtkArg    *arg,
guint      arg_id);




/* Default signal handler for the ::destroy signal, which is




invoked to request that references to the widget be dropped.
If an object class overrides destroy() in order to perform class
specific destruction then it must still invoke its superclass'
implementation of the method after it is finished with its
own cleanup. (See gtk_widget_real_destroy() for an example of
how to do this).
*/
void (*destroy)  (GtkObject *object);
};
  • invoked to request that references to the widget be dropped.
  • If an object class overrides destroy() in order to perform class
  • specific destruction then it must still invoke its superclass'
  • implementation of the method after it is finished with its
  • own cleanup. (See gtk_widget_real_destroy() for an example of
  • how to do this). */ void (*destroy) (GtkObject *object); };

The (*set_arg) stuff is a pointer to function and this can e.g be assigned another implementation in some derived class.

Often you see something like this

struct function_table {
   char *name;
   void (*some_fun)(int arg1, double arg2);
};

void function1(int  arg1, double arg2)....


struct function_table my_table [] = {
    {"function1", function1},
...

So you can reach into the table by name and call the "associated" function.

Or maybe you use a hash table in which you put the function and call it "by name".

Regards
Friedrich

Solution 7 - C

Can use it in the way like this:

//! Define:
#define F_NUM 3
int (*pFunctions[F_NUM])(void * arg);

//! Initialise:
int someFunction(void * arg) {
    int a= *((int*)arg);
    return a*a;
}

pFunctions[0]= someFunction;

//! Use:
int someMethod(int idx, void * arg, int * result) {
    int done= 0;
    if (idx < F_NUM && pFunctions[idx] != NULL) {
        *result= pFunctions[idx](arg);
        done= 1;
    }
    return done;
}

int x= 2;
int z= 0;
someMethod(0, (void*)&x, &z);
assert(z == 4);

Solution 8 - C

This should be a short & simple copy & paste piece of code example of the above responses. Hopefully this helps.

#include <iostream>
using namespace std;

#define DBG_PRINT(x) do { std::printf("Line:%-4d" "  %15s = %-10d\n", __LINE__, #x, x); } while(0);

void F0(){ printf("Print F%d\n", 0); }
void F1(){ printf("Print F%d\n", 1); }
void F2(){ printf("Print F%d\n", 2); }
void F3(){ printf("Print F%d\n", 3); }
void F4(){ printf("Print F%d\n", 4); }
void (*fArrVoid[N_FUNC])() = {F0, F1, F2, F3, F4};

int Sum(int a, int b){ return(a+b); }
int Sub(int a, int b){ return(a-b); }
int Mul(int a, int b){ return(a*b); }
int Div(int a, int b){ return(a/b); }
int (*fArrArgs[4])(int a, int b) = {Sum, Sub, Mul, Div};

int main(){
    for(int i = 0; i < 5; i++)	(*fArrVoid[i])();
    printf("\n");

    DBG_PRINT((*fArrArgs[0])(3,2))
    DBG_PRINT((*fArrArgs[1])(3,2))
    DBG_PRINT((*fArrArgs[2])(3,2))
    DBG_PRINT((*fArrArgs[3])(3,2))

    return(0);
}

Solution 9 - C

The simplest solution is to give the address of the final vector you want , and modify it inside the function.

void calculation(double result[] ){  //do the calculation on result

   result[0] = 10+5;
   result[1] = 10 +6;
   .....
}

int main(){

    double result[10] = {0}; //this is the vector of the results

    calculation(result);  //this will modify result
}

Solution 10 - C

This question has been already answered with very good examples. The only example that might be missing is one where the functions return pointers. I wrote another example with this, and added lots of comments, in case someone finds it helpful:

#include <stdio.h>

char * func1(char *a) {
    *a = 'b';
    return a;
}

char * func2(char *a) {
    *a = 'c';
    return a;
}

int main() {
    char a = 'a';
    /* declare array of function pointers
     * the function pointer types are char * name(char *)
     * A pointer to this type of function would be just
     * put * before name, and parenthesis around *name:
     *   char * (*name)(char *)
     * An array of these pointers is the same with [x]
     */
    char * (*functions[2])(char *) = {func1, func2};
    printf("%c, ", a);
    /* the functions return a pointer, so I need to deference pointer
     * Thats why the * in front of the parenthesis (in case it confused you)
     */
    printf("%c, ", *(*functions[0])(&a)); 
    printf("%c\n", *(*functions[1])(&a));

    a = 'a';
    /* creating 'name' for a function pointer type
     * funcp is equivalent to type char *(*funcname)(char *)
     */
    typedef char *(*funcp)(char *);
    /* Now the declaration of the array of function pointers
     * becomes easier
     */
    funcp functions2[2] = {func1, func2};

    printf("%c, ", a);
    printf("%c, ", *(*functions2[0])(&a));
    printf("%c\n", *(*functions2[1])(&a));

    return 0;
}

Solution 11 - C

This simple example for multidimensional array with function pointers":

void one( int a, int b){    printf(" \n[ ONE ]  a =  %d   b = %d",a,b);}
void two( int a, int b){    printf(" \n[ TWO ]  a =  %d   b = %d",a,b);}
void three( int a, int b){    printf("\n [ THREE ]  a =  %d   b = %d",a,b);}
void four( int a, int b){    printf(" \n[ FOUR ]  a =  %d   b = %d",a,b);}
void five( int a, int b){    printf(" \n [ FIVE ]  a =  %d   b = %d",a,b);}
void(*p[2][2])(int,int)   ;
int main()
{
    int i,j;
    printf("multidimensional array with function pointers\n");

    p[0][0] = one;    p[0][1] = two;    p[1][0] = three;    p[1][1] = four;
    for (  i  = 1 ; i >=0; i--)
        for (  j  = 0 ; j <2; j++)
            (*p[i][j])( (i, i*j);
    return 0;
}

Solution 12 - C

#include <iostream>
using namespace std;
    
int sum (int , int);
int prod (int , int);
    
int main()
{
	int (*p[2])(int , int ) = {sum,prod};
    
	cout << (*p[0])(2,3) << endl;
	cout << (*p[1])(2,3) << endl;
}
    
int sum (int a , int b)
{
	return a+b;
}
    
int prod (int a, int b)
{
	return a*b;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjohnView Question on Stackoverflow
Solution 1 - CVonCView Answer on Stackoverflow
Solution 2 - CManoj DoubtsView Answer on Stackoverflow
Solution 3 - CRasmi Ranjan NayakView Answer on Stackoverflow
Solution 4 - CM.MView Answer on Stackoverflow
Solution 5 - CAlex HajnalView Answer on Stackoverflow
Solution 6 - CFriedrichView Answer on Stackoverflow
Solution 7 - CPeter HirtView Answer on Stackoverflow
Solution 8 - Cnimig18View Answer on Stackoverflow
Solution 9 - CLeonardoView Answer on Stackoverflow
Solution 10 - CJay MedinaView Answer on Stackoverflow
Solution 11 - Carun kumarView Answer on Stackoverflow
Solution 12 - Csra jsView Answer on Stackoverflow