204 votes

Comment utiliser un tableau de pointeurs de fonctions ?

Comment utiliser un tableau de pointeurs de fonctions en C ?

Comment puis-je les initialiser ?

261voto

VonC Points 414372

Vous avez un bon exemple ici (tableau de pointeurs de fonctions) avec le syntaxe détaillée .

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

Pour appeler un de ces pointeurs de fonction :

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

60voto

Manoj Doubts Points 2080

Oui, les réponses ci-dessus peuvent vous aider, mais vous voulez peut-être aussi savoir comment utiliser un tableau de pointeurs de fonction.

void fun1()
{

}
void fun2()
{

}
void fun3()
{

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

main()
{
 int option;

    printf("\nEnter function number u want");
     printf("\nyou should not enter other than 0 , 1, 2"); /*bcos we hav only 3 functions*/
     scanf("%d",&option);

     if((option>=0)&&(option<=2))
       { 
         (*func_ptr[option])();
       }

   return 0;
}

vous ne pouvez affecter les adresses des fonctions ayant le même type de retour et les mêmes types d'arguments et le même nombre d'arguments qu'à un seul tableau de pointeurs de fonctions.

vous pouvez également passer des arguments comme ci-dessous si toutes les fonctions ci-dessus ont le même nombre d'arguments de même type.

  (*func_ptr[option])(argu1);

ok expérimentez-le. note : ici, dans le tableau, la numérotation des pointeurs de fonction commencera à partir de 0, comme dans les tableaux généraux, donc dans l'exemple ci-dessus

fun1 est accessible si l'option=0,

fun2() peut être appelé si option=1 et

fun3() peut être appelé si l'option=2.

11voto

Rasmi Ranjan Nayak Points 1721

Jetez un coup d'œil Fichier *New_Fun.h*

#ifndef _NEW_FUN_H_
#define _NEW_FUN_H_

#include<stdio.h>

typedef int speed;
speed fun(int x);

int (*array_fun[100])(int x, int y);

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

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

Fichier *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");
}

Fichier Main.c

#include <stdio.h>
#include <stdlib.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 incompatable is bound to happen
    int xyz, i;
    i = 0;
    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;
    }

J'espère que cela vous aidera à comprendre Function Pointer.

9voto

Matt McNabb Points 14273

Cette "réponse" est plutôt un addendum à la réponse de VonC ; je note simplement que la syntaxe peut être simplifiée via un typedef, et que l'initialisation par agrégat peut être utilisée :

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

2voto

Friedrich Points 4058

Oh, il y a des tonnes d'exemples. Il suffit de regarder tout ce qui se trouve dans glib ou gtk. Vous pouvez voir le travail des pointeurs de fonction dans le travail là tout le chemin.

Ici, par exemple, l'initialisation de la chose 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;

Et dans gtkobject.h vous trouvez les déclarations suivantes :

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

L'élément (*set_arg) est un pointeur vers une fonction et celle-ci peut par exemple être assignée à une autre implémentation dans une classe dérivée.

On voit souvent quelque chose comme ceci

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

Vous pouvez donc accéder à la table par son nom et appeler la fonction "associée".

Ou peut-être utilisez-vous une table de hachage dans laquelle vous placez la fonction et l'appelez "par son nom".

Salutations
Friedrich

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X