How can I use an array of function pointers?

前端 未结 10 1140
别那么骄傲
别那么骄傲 2020-11-22 17:24

How should I use array of function pointers in C?

How can I initialize them?

相关标签:
10条回答
  • 2020-11-22 17:36

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 17:43

    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);
    };
    

    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

    0 讨论(0)
  • 2020-11-22 17:44

    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.

    0 讨论(0)
  • 2020-11-22 17:52

    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);
    
    0 讨论(0)
提交回复
热议问题