how - pointer to function




كيف يمكنني استخدام مجموعة من مؤشرات الوظائف؟ (6)

كيف يمكنني استخدام مجموعة من مؤشرات الوظائف في C؟

كيف يمكنني تهيئة لهم؟


أوه، هناك طن من الأمثلة. مجرد إلقاء نظرة على أي شيء داخل غليب أو غك. يمكنك أن ترى عمل مؤشرات وظيفة في العمل هناك على طول الطريق.

هنا على سبيل المثال تهيئة الأشياء 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;

وفي gtkobject.h تجد الإعلانات التالية:


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

و (* set_arg) الاشياء هو مؤشر على وظيفة وهذا يمكن على سبيل المثال يتم تعيين تنفيذ آخر في بعض الطبقة المشتقة.

في كثير من الأحيان ترى شيئا من هذا القبيل

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

حتى تتمكن من الوصول إلى الجدول بالاسم واستدعاء وظيفة "المرتبطة".

أو ربما كنت تستخدم جدول التجزئة التي وضعت وظيفة وندعوها "بالاسم".

مع تحياتي
فريدريش


لديك مثال جيد هنا (صفيف من مؤشرات وظيفة) ، مع بناء الجملة مفصلة .

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

لاستدعاء واحدة من تلك المؤشرات وظيفة:

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

الإجابات أعلاه قد تساعدك ولكن قد ترغب أيضا في معرفة كيفية استخدام مجموعة من مؤشرات وظيفة.

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

يمكنك فقط تعيين عناوين الدالات بنفس نوع الإرجاع وأنواع الوسيطة نفسها وأي من الوسيطات إلى صفيف مؤشر الدالة المفرد.

يمكنك أيضا تمرير الوسيطات مثل أدناه إذا كانت جميع الدوال أعلاه تحتوي على نفس عدد الوسيطات من نفس النوع.

  (*func_ptr[option])(argu1);

ملاحظة: هنا في صفيف الترقيم من مؤشرات وظيفة سوف تبدأ من 0 نفسه كما هو الحال في المصفوفات العامة. حتى في المثال أعلاه fun1 يمكن أن يسمى إذا الخيار = 0، fun2 يمكن أن يسمى إذا الخيار = 1 و fun3 يمكن أن يسمى إذا الخيار = 2.


وقد تم الإجابة على هذا السؤال بالفعل مع أمثلة جيدة جدا. والمثال الوحيد الذي قد يكون مفقودا هو مثال حيث تقوم الدالات بإرجاع المؤشرات. كتبت مثالا آخر مع هذا، وأضاف الكثير من التعليقات، في حالة شخص ما يجد أنه من المفيد:

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

هذا المثال البسيط للمصفوفة متعددة الأبعاد بمؤشرات الدالة ":

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

أبسط حل هو إعطاء عنوان المتجه النهائي الذي تريده، وتعديله داخل الدالة.

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
}




function-pointers