如何在 C 中使用两个返回不同类型的函数作为函数指针?



我有一个创建函数,我想传递一个函数指针,但是我希望函数指针能够调用下面的任何一个函数,我遇到的问题是每个函数都返回不同的类型。但是当我传递函数指针时,我必须指定函数指针的返回类型。这是对的吗? 我以为在 中使用 void 指针可以解决返回类型问题,但现在我无法调用函数指针。为了澄清,我想将populateMonsterspopulateClassesTaken传递到create中,并能够在create内调用它们。

typedef struct node{
void * data;
struct node* next;
} node;
typedef struct MonsterAttacks{
unsigned int attackID;
char monsterName[41];
char attackLocation[41];
unsigned int numOfVictims;
}MonsterAttacks;
typedef struct ClassesTaken{
unsigned int classID;
char semester[41];
unsigned int year;
unsigned int numberOfUnits;
char grade[10];
}ClassesTaken;

unsigned int idM = 1;
MonsterAttacks * populateMonsters(){
MonsterAttacks *m = NULL;
m->attackID = idM;
printf("Enter the name for the Monster n");
scanf("%40s",m->monsterName);
puts("What is his/her attack location?");
scanf("%40s",m->attackLocation);
puts("What are the number of victims this monster has demolished?");
scanf("%ud", &m->numOfVictims);      
//attackID is assigned and id when node is created
idM++;
return m;
}
unsigned int idC = 1;
ClassesTaken* populateClassesTaken(){
ClassesTaken *c = NULL;
c->classID = idC;
scanf("What semester was the class taken in? %40s",c->semester);
scanf("In what year? %ud", &c->year);  
scanf("How many units was the class? %ud", &c->numberOfUnits);
scanf("What was your grade in the class? %9s", c->grade);     

idC++;
return c;
}
node* create(node* next, void *fp)
{
node* new_node = (node*)malloc(sizeof(node));
if(new_node == NULL)
{
printf("Error creating a new node.n");
exit(0);
}
void *data = (*fp)();
}

int main(void)
{
node* tmp = NULL;
MonsterAttacks* (*fp)() = &populateMonsters;
create(tmp, *fp);
}

首先,不用说你不能像ClassesTaken *c = NULL; c->classID = idC;那样编写代码。如果你不明白为什么你不能,你需要回到学习指针的基础知识,如下所述: 将数据复制/扫描/读取到未初始化的指针时崩溃或"分段错误">

至于不同的功能 - 它们是不同的功能类型这一事实清楚地表明这种设计没有意义。如果要使用泛型函数指针,则需要定义统一的函数格式,例如void* func (void)

不能void*用作泛型函数指针。它仅用于指向对象的指针,而不是指向函数的指针。create(tmp, *fp);等代码,其中 fp 是函数指针,函数需要void*,不是有效的标准 C,不应编译,除非您使用的是非标准编译器扩展。

值得注意的是,切勿在 C 中声明带有空括号()的函数。这是一个过时的语言功能。(与C++不同,这很好,很鼓励。

populateMonsters()populateClassesTaken()仍然存在问题。您希望用用户输入填充结构,但从不分配结构(无论是在堆上还是在堆栈上(。因此,您会出现分段错误。这是我没有类型定义的代码,包括,...

typedef void*(*myFunctionInterface)(void);
MonsterAttacks * populateMonsters (){
MonsterAttacks *m = (MonsterAttacks*)malloc(sizeof(MonsterAttacks));
if (m == NULL){
printf("Error creating MonsterAttacks");
exit (-1);
}
m->attackID = idM;
printf ("Enter the name for the Monster n");
scanf ("%40s", m->monsterName);
puts ("What is his/her attack location?");
scanf ("%40s", m->attackLocation);
puts ("What are the number of victims this monster has demolished?");
scanf ("%ud", &m->numOfVictims);
//attackID is assigned and id when node is created
idM++;
return m;
}
unsigned int idC = 1;
ClassesTaken * populateClassesTaken (){
ClassesTaken *c = (ClassesTaken*)malloc(sizeof(ClassesTaken));
if (c == NULL){
printf("Error creating ClassesTaken");
exit(-2);
}
c->classID = idC;
scanf ("What semester was the class taken in? %40s", c->semester);
scanf ("In what year? %ud", &c->year);
scanf ("How many units was the class? %ud", &c->numberOfUnits);
scanf ("What was your grade in the class? %9s", c->grade);

idC++;
return c;
}
node * create (node * next, void *(*fp) ()){
node *new_node = (node *) malloc (sizeof (node));
if (new_node == NULL)
{
printf ("Error creating a new node.n");
exit (-3);
}
void *data = fp();
new_node->data = data;
return new_node;
}

int main (void) {    
node *tmp = NULL;
MonsterAttacks *(*fp_M) () = &populateMonsters;
ClassesTaken *(*fp_C) () = &populateClassesTaken;
create (tmp, (myFunctionInterface)fp_M);
}

在出现错误时返回 0 也不是一个好的样式。 0 通常表示一切正常。因此,我将退出值更改为一些不同的负数以区分错误

替换:

node* create(node* next, void *fp)
{

跟:

node* create(node* next, void* (*fp)())
{

create(tmp, *fp);

create(tmp, (void*)fp); //[updated]

您的 populateMonsters(( 会导致分段错误。我用fputs("In populateMonstersn", stderr);替换了它的代码

它似乎有效:

$ ./a.out

在填充怪物中

最新更新