How pointers to function as struct member useful in C?

12,130

Solution 1

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.

Solution 2

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

Solution 3

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"

Solution 4

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

Solution 5

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

Share:
12,130
Grijesh Chauhan
Author by

Grijesh Chauhan

I am a web backend developer, mostly write codes in Python, C and Go. I am a postgraduate in Computer Engineering I am a new contributor on Github and HackerRank. I also enjoy teaching and research work. Interesting Reads: Bit Twiddling Hacks Use reentrant functions for safer signal handling SARGable I always read some programming book. Top books in my rack are: Beginning Linux Programming, 4th Edition Python Cookbook, 3rd Edition Python-DataScience-Handbook Text Processing in Python by David Mertz, Amazon.com I think "IPython Cookbook" would be the next book to place on the stack!

Updated on July 06, 2022

Comments

  • Grijesh Chauhan
    Grijesh Chauhan almost 2 years

    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.