How pointers to function as struct member useful in C?
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
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, 2022Comments
-
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
, evenfun()
is member of struct.If its good to keep function pointer within struct definition, kindly help to explain the the reason.