Reputation: 58271
I am not new to C programming. But I don't understand why keeping a pointer to a function as a structure member is useful in C. Example:
// 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);
}
Do programmers use it to give an Object-Oriented (OO) shape to their C code and provide abstract objects, or just to make code look technical?
I think that in the above code the second way is more gentle and pretty simple too. In the first way, we still have to pass &var
, even though fun()
is member of the struct.
If it's good to keep function pointers within a struct definition, kindly explain the reason.
Upvotes: 8
Views: 13214
Reputation: 13651
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.
Upvotes: 11
Reputation: 8206
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
Upvotes: 1
Reputation: 123448
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"
Upvotes: 2
Reputation: 1113
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.
Upvotes: 1
Reputation: 25695
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;
}
Upvotes: 11
Reputation: 20980
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
Upvotes: 1