How pointers to function as struct member useful i

2019-01-17 23:50发布

I am not new to C programming. But I don't understand what is usefulness to keep pointer to function as a structure member in C. e.g.

    // Fist Way: To keep pointer to function in struct
    struct newtype{
        int a;
        char c;
        int (*f)(struct newtype*);
    } var;
    int fun(struct newtype* v){
        return v->a;
    }

    // Second way: Simple
    struct newtype2{
        int a;
        char c;
    } var2;
    int fun2(struct newtype2* v){
        return v->a;
    }

    int main(){

        // Fist: Require two steps
        var.f=fun;
        var.f(&var);

        //Second : simple to call
        fun2(&var2);    
    }

Does programmers use it to give Object Oriented(OO) shape to there C code and provide abstract object? Or to make code look technical.

I think, in above code second way is more gentle and pretty simple too. In fist way, we still have to pass &var, even fun() is member of struct.

If its good to keep function pointer within struct definition, kindly help to explain the the reason.

6条回答
聊天终结者
2楼-- · 2019-01-18 00:30

Providing a pointer to function on a structure can enable you to dynamically choose which function to perform on a structure.

struct newtype{
    int a;
    int b;
    char c;
    int (*f)(struct newtype*);
} var;


int fun1(struct newtype* v){
        return v->a;
    }

int fun2(struct newtype* v){
        return v->b;
    }

void usevar(struct newtype* v) {
   // at this step, you have no idea of which function will be called
   var.f(&var);
}

int main(){
        if (/* some test to define what function you want)*/) 
          var.f=fun1;
        else
          var.f=fun2;
        usevar(var);
    }

This gives you the ability to have a single calling interface, but calling two different functions depending on if your test is valid or not.

查看更多
【Aperson】
3楼-- · 2019-01-18 00:36

Its useful if you're trying to do some sort of "object based" programming.

If you've ever seen the Quake 3 engine's source code.. you can see clearly that most "entities" have attributes that define them, and the work they do[which are the function pointers].

Segregating attributes and functions(through function pointers in C) defines a "struct" object's attributes and actions they can do.

For example:

struct _man{
   char name[];
   int age;
   void (*speak)(char *text);
   void (*eat)(Food *foodptr);
   void (*sleep)(int hours); 
   /*etc*/
};

void grijesh_speak(char *text)
{
   //speak;
}

void grijesh_eat(Food *food)
{
   //eat
}

void grijesh_sleep(int hours)
{
   //sleep
}

void init_struct(struct _man *man)
{
    if(man == NULL){ man = malloc(sizeof(struct _man));}
      strcpy(*man.name,"Grijesh");
      man->age = 25;
      man->speak = grijesh_speak;
      man->eat = grijesh_food;
      man->sleep = grijesh_sleep;
//etc
}

//so now in main.. i can tell you to either speak, or eat or sleep.

int main(int argc, char *argv[])
{
    struct _man grijesh;
    init_struct(&grijesh);
    grijesh.speak("Babble Dabble");
    grijesh.sleep(10);
    return 0;
}
查看更多
一夜七次
4楼-- · 2019-01-18 00:39

Here is a project to help explain the usefulness of function pointers. Try to create a c-based library providing inheritance and polymorphism. Or, try and recreate "C with Classes". Function pointers inside structures will be vital. http://www.cs.rit.edu/~ats/books/ooc.pdf

查看更多
戒情不戒烟
5楼-- · 2019-01-18 00:40

Sometimes in C you need to call a function, without knowing its implementation upfront. E.g. if you're developing a stand-alone library used in different projects. In that case, it makes perfect sense to add a function pointer to a context struct and pass that along to the library functions. The library functions can then call your function at run-time without having to include the header files that define it.

It is indeed similar to what you do when doing Object Oriented programming. In C, you usually pass around context variables, e.g. a struct, grouping together a set of variables and possibly functions that are meaningful for that context. This is close to the eqvuivalent in OO programming, where you instantiate a class and set the required variables on the instance.

查看更多
Evening l夕情丶
6楼-- · 2019-01-18 00:43

I've used this in the past to implement generic containers1 in C.

For example:

typedef struct generic_list_node {
  void *data;
  struct generic_list_node *next;
} generic_list_node_t;

typedef struct generic_list {
  generic_list_node_t *head;
  void *(*copy)(void *data);                 
  void (*delete)(void *data);                
  int (*compare)(void *lhs, void *rhs);      
  void (*display)(void *data, FILE *stream);
} generic_list_t;

The list structure itself is data-agnostic, using void * to represent data items, and delegates all type-aware operations to the functions indicated by the pointers above:

int insert(generic_list_t l, void *data)
{
  generic_list_node_t *cur = l.head;
  generic_list_node_t *new = malloc(sizeof *new);
  if (new)
  {
    new->data = l.copy(data);
    new->next = NULL;

    if (l.head == NULL)
    {
      l.head = new;
    }
    else
    {
      while (cur->next && l.compare(new->data, cur->data) > 0)
        cur = cur->next;
      new->next = cur->next;
      cur->next = new;
      printf("Successfully added ");
      l.display(data, stdout);
      printf(" to list\n");

    }
    return 1;
  }

  return 0;
}

1. For suitably loose definitions of "generic" and "container"

查看更多
我想做一个坏孩纸
7楼-- · 2019-01-18 00:49

This can be particuarly useful in embedded system, or driver writing. The functions are called using function pointers.

e.g.

struct_my_filesystem.open=my_open;
struct_my_filesystem.read=my_read;

etc

查看更多
登录 后发表回答