如何在C中使用作为struct成员的指针?

我不是C编程的新手。 但是我不明白将指针作为C中的结构成员保持指示是有用的。例如

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

程序员是否使用它来为C代码提供面向对象(OO)形状并提供抽象对象? 或者使代码看起来技术性。

我认为,在上面的代码中,第二种方式也更温和,也很简单。 首先,我们仍然必须传递&var ,甚至fun()是struct的成员。

如果将结构定义中的函数指针保持良好,请帮助解释其原因。

提供指向结构上的函数的指针可以使您能够动态选择要对结构执行的函数。

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

这使您能够拥有一个调用接口,但根据您的测试是否有效调用两个不同的函数。

如果您尝试进行某种“基于对象”的编程,它很有用。

如果您曾经见过Quake 3引擎的源代码,您可以清楚地看到大多数“实体”具有定义它们的属性,以及它们所做的工作[它们是函数指针]。

隔离属性和函数(通过C中的函数指针)定义了“struct”对象的属性和它们可以执行的操作。

例如:

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

我过去曾用过这个来实现C中的通用容器1

例如:

 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; 

列表结构本身与数据无关,使用void *表示数据项,并将所有类型感知操作委托给上面指针指示的函数:

 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.对于“通用”和“容器”的适当松散定义

这在嵌入式系统或驱动程序编写中尤其有用。 使用函数指针调用这些函数。

例如

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

等等

有时在C中你需要调用一个函数,而不需要事先知道它的实现。 例如,如果您正在开发在不同项目中使用的独立库。 在这种情况下,将函数指针添加到上下文结构并将其传递给库函数是完全合理的。 然后,库函数可以在运行时调用您的函数,而不必包含定义它的头文件。

它确实类似于您在进行面向对象编程时所执行的操作。 在C中,您通常会传递上下文变量,例如结构,将一组变量和可能对该上下文有意义的函数组合在一起。 这接近于OO编程中的eqvuivalent,您可以实例化一个类并在实例上设置所需的变量。

这是一个帮助解释函数指针有用性的项目。 尝试创建一个基于c的库,提供inheritance和多态。 或者,尝试重新创建“C with Classes”。 结构内部的函数指针将至关重要。 http://www.cs.rit.edu/~ats/books/ooc.pdf