Como posso usar uma matriz de pointers de function?

Como devo usar uma matriz de pointers de function em C?

Como posso inicializá-los?

    Você tem um bom exemplo aqui (Array of Function Pointers) , com a syntax detalhada .

    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() */ [...] 

    Para chamar um desses pointers de function:

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

    As respostas acima podem ajudá-lo, mas você também pode querer saber como usar a matriz de pointers de function.

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

    Você só pode atribuir os endereços de funções com o mesmo tipo de retorno e os mesmos tipos de argumentos e nenhum dos argumentos para uma única matriz de ponteiro de function.

    Você também pode passar argumentos como abaixo se todas as funções acima tiverem o mesmo número de argumentos do mesmo tipo.

      (*func_ptr[option])(argu1); 

    Nota: aqui na matriz, a numeração dos pointers da function será iniciada a partir de 0 igual aos arrays gerais. Portanto, no exemplo acima, fun1 pode ser chamado se option = 0, fun2 pode ser chamado se option = 1 e fun3 podem ser chamados se option = 2.

    Veja como você pode usá-lo:

    New_Fun.h

     #ifndef NEW_FUN_H_ #define NEW_FUN_H_ #include  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  #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; } 

    Espero que isso ajude na compreensão do Function Pointer.

    Essa “resposta” é mais um adendo à resposta da VonC; apenas observando que a syntax pode ser simplificada por meio de um typedef e a boot agregada pode ser usada:

     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 ab; } int mul(int a, int b) { return a*b; } int div(int a, int b) { return a/b; } 

    Oh, há toneladas de exemplo. Basta dar uma olhada em qualquer coisa dentro do glib ou gtk. Você pode ver o trabalho de pointers de function no trabalho até o fim.

    Aqui, por exemplo, a boot do material gtk_button.

     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; 

    E no gtkobject.h você encontra as seguintes declarações:

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

    O material (* set_arg) é um ponteiro para a function e isso pode, por exemplo, ser atribuído a outra implementação em alguma class derivada.

    Muitas vezes você vê algo parecido com isto

     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}, ... 

    Assim, você pode acessar a tabela pelo nome e chamar a function “associada”.

    Ou talvez você use uma tabela de hash na qual você coloca a function e a chama “pelo nome”.

    Saudações
    Friedrich

    Este deve ser um exemplo simples e curto de copiar e colar de código das respostas acima. Espero que isso ajude.

     #include  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(ab); } 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); } 

    Esta questão já foi respondida com exemplos muito bons. O único exemplo que pode estar faltando é aquele em que as funções retornam pointers. Escrevi outro exemplo com isso e adicionei muitos comentários, no caso de alguém achar útil:

     #include  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; } 

    Este exemplo simples para array multidimensional com pointers de function “:

     void one( int a, int b){ printf(" \n[ ONE ] a = %db = %d",a,b);} void two( int a, int b){ printf(" \n[ TWO ] a = %db = %d",a,b);} void three( int a, int b){ printf("\n [ THREE ] a = %db = %d",a,b);} void four( int a, int b){ printf(" \n[ FOUR ] a = %db = %d",a,b);} void five( int a, int b){ printf(" \n [ FIVE ] a = %db = %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; } 

    A solução mais simples é fornecer o endereço do vetor final desejado e modificá-lo dentro da 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 } 

    Pode usá-lo da seguinte forma:

     //! 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);