如何使用两个 return 不同类型的函数作为 C 中的函数指针?
How to use two functions that return different types as a function pointer in C?
我有一个创建函数,我想传递一个函数指针,但是我希望函数指针能够调用下面的任何一个函数,我遇到的问题是每个 return一种不同的类型。但是当我传递函数指针时,我必须指定函数指针的 return 类型。这个对吗?
我以为在里面用一个void指针就可以解决return类型的问题,但是现在我不能调用函数指针了。为了澄清,我想将 populateMonsters
或 populateClassesTaken
传递给 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);
}
替换:
node* create(node* next, void *fp)
{
与:
node* create(node* next, void* (*fp)())
{
和
create(tmp, *fp);
和
create(tmp, (void*)fp); //[updated]
您的 populateMonsters() 导致分段错误。我用 fputs("In populateMonsters\n", stderr);
替换了它的代码
它似乎起作用了:
$ ./a.out
In populateMonsters
populateMonsters()
和 populateClassesTaken()
中仍有问题。你想用用户输入填充结构,但你从不分配结构(既不在堆上也不在堆栈上)。因此,您会遇到分段错误。这是我没有 typedef 的代码,包括,...
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);
}
如果出现错误,return0 也不是一个好的样式。 0 通常表示一切正常。因此,我将退出值更改为一些不同的负数以区分错误
首先,不言而喻,你不能写出ClassesTaken *c = NULL; c->classID = idC;
这样的代码。如果你不明白为什么你不能,你需要回去学习指针的基础知识,如下所述:
至于不同的功能 - 它们 是 不同的功能类型这一事实清楚地表明这种设计没有意义。如果你希望使用通用函数指针,你需要定义一个统一的函数格式,例如void* func (void)
.
您不能使用void*
作为通用函数指针。它仅定义为与指向对象的指针一起使用,而不是与函数一起使用。诸如 create(tmp, *fp);
之类的代码,其中 fp 是一个函数指针并且该函数期望 void*
是无效的标准 C,不应编译,除非您使用的是非标准编译器扩展。
值得注意的是,您永远不应该在 C 中用空括号 ()
声明函数。这是一种过时的语言功能。 (与 C++ 不同,在 C++ 中这是很好的并且受到鼓励。)
我有一个创建函数,我想传递一个函数指针,但是我希望函数指针能够调用下面的任何一个函数,我遇到的问题是每个 return一种不同的类型。但是当我传递函数指针时,我必须指定函数指针的 return 类型。这个对吗?
我以为在里面用一个void指针就可以解决return类型的问题,但是现在我不能调用函数指针了。为了澄清,我想将 populateMonsters
或 populateClassesTaken
传递给 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);
}
替换:
node* create(node* next, void *fp)
{
与:
node* create(node* next, void* (*fp)())
{
和
create(tmp, *fp);
和
create(tmp, (void*)fp); //[updated]
您的 populateMonsters() 导致分段错误。我用 fputs("In populateMonsters\n", stderr);
它似乎起作用了:
$ ./a.out
In populateMonsters
populateMonsters()
和 populateClassesTaken()
中仍有问题。你想用用户输入填充结构,但你从不分配结构(既不在堆上也不在堆栈上)。因此,您会遇到分段错误。这是我没有 typedef 的代码,包括,...
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);
}
如果出现错误,return0 也不是一个好的样式。 0 通常表示一切正常。因此,我将退出值更改为一些不同的负数以区分错误
首先,不言而喻,你不能写出ClassesTaken *c = NULL; c->classID = idC;
这样的代码。如果你不明白为什么你不能,你需要回去学习指针的基础知识,如下所述:
至于不同的功能 - 它们 是 不同的功能类型这一事实清楚地表明这种设计没有意义。如果你希望使用通用函数指针,你需要定义一个统一的函数格式,例如void* func (void)
.
您不能使用void*
作为通用函数指针。它仅定义为与指向对象的指针一起使用,而不是与函数一起使用。诸如 create(tmp, *fp);
之类的代码,其中 fp 是一个函数指针并且该函数期望 void*
是无效的标准 C,不应编译,除非您使用的是非标准编译器扩展。
值得注意的是,您永远不应该在 C 中用空括号 ()
声明函数。这是一种过时的语言功能。 (与 C++ 不同,在 C++ 中这是很好的并且受到鼓励。)