Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 调用函数指针(语法)_C_Function_Pointers_Struct - Fatal编程技术网

C 调用函数指针(语法)

C 调用函数指针(语法),c,function,pointers,struct,C,Function,Pointers,Struct,假设我有一个函数,它接受这些参数 int create(Ptr * p,void * (*insert)(void *, void *)) { //return something later } 结构: typedef struct { void ** ptr; void * (*insert)(void *, void *)); }Ptr; 其中p是指向结构的指针,insert是指向具有两个通用指针(void指针)的函数的函数指针,用于在给定树中插入整数(我使用void指针,因为在本例

假设我有一个函数,它接受这些参数

int create(Ptr * p,void * (*insert)(void *, void *)) {

//return something later
}
结构:

typedef struct {
void ** ptr;
void * (*insert)(void *, void *));
}Ptr;
其中p是指向结构的指针,insert是指向具有两个通用指针(void指针)的函数的函数指针,用于在给定树中插入整数(我使用void指针,因为在本例中它是整数,在其他情况下可能不是)

在这里,我如何调用函数create

我知道我可以对第一个参数做一些类似的事情:

//在一个单独的.c文件中

Ptr * pt;
pt = malloc(sizeof(Ptr));

create(pt,....what to put here)?

如果我想将结构指针作为参数传递,然后再插入一个整数(同样,它们都是void指针,因为它是一个泛型构建)

在该函数中,您可以编写以下任一项:

insert(vp1, vp2);
或:

我假设:

void *vp1 = …;
void *vp2 = …;
第二种是C89/C90标准之前所必需的形式;你会发现像我这样的老顽固仍然喜欢它。第一个是自标准的第一个版本发布以来的标准,但您必须查看函数的参数列表才能发现
insert
是指向函数的指针,而不是函数名。这就是为什么我仍然喜欢旧的符号

对于实际调用函数,只需给出与
insert
函数指针签名匹配的函数名称:

extern void *insert_int(void *vp1, void *vp2);

if (create(pt, insert_int) != 0)
    …handle error…

根据创建的定义

void*  mine(void* x, void* y)
{
   return NULL
}

create(pt, mine);
而创造将是

int create(Ptr * p,void * (*insert)(void *, void *)) {
   p->insert = insert;
}
我会使用一个函数来进行调用

void* ptr_insert(Ptr* p, void* a, void* b)
{
   if(p!=NULL && p->insert != NULL) return p->insert(a,b); 
   return NULL;
}

一些可编译的示例用法:

typedef struct {
  void ** ptr;
  void * (*insert)(void *, void *);
} Ptr;
int create(Ptr * p,void * (*insert)(void *, void *));

void* Insert(void*, void*);

void fun(){
  Ptr ptr;
  Ptr * pt = &ptr;

  //Function name decays to its addresss
  create(pt, &Insert);
  create(pt, Insert);  //the same thing

  //Declare a pointer
  void* (*ins)(void*, void*);
  //Assing to it
  ins = &Insert;
  //Same thing
  ins = Insert;

  //Invocation via pointer
  void* ret = (*ins)(pt, pt);

  //Same thing
  ret = ins(pt, pt);

  //Passs the pointer
  create(pt, ins);
}

谢谢,而且我也不太确定一旦传入create,我会如何处理这些参数?我被告知要存储他们的地址,因为这个函数只用于初始化一棵树。其中有一个元素是“我也不知道你想对他们做什么”。我不清楚您的
create()
函数指定要做什么-因为这是它应该做的。如果没有全部的家庭作业,我就不能告诉你该做什么。有很多编写代码的方法——其中一些是好的,许多是坏的,几乎所有的方法都可以在某处找到。我不知道你打算用
void**ptr做什么结构的成员。我还差一英里呢。也许您只是简单地复制
insert
成员上的
insert
参数?更重要的是,我没有复制整个代码,以减少冗余。因此,create函数的参数不能完全表示,structs字段也不能完全表示。我认为设计是错误的。您应该定义
insert
函数,并且不应该将其作为参数传递给
create
函数(因为我假设您不需要为树中的每个节点都使用单独的
insert
函数)。
typedef struct {
  void ** ptr;
  void * (*insert)(void *, void *);
} Ptr;
int create(Ptr * p,void * (*insert)(void *, void *));

void* Insert(void*, void*);

void fun(){
  Ptr ptr;
  Ptr * pt = &ptr;

  //Function name decays to its addresss
  create(pt, &Insert);
  create(pt, Insert);  //the same thing

  //Declare a pointer
  void* (*ins)(void*, void*);
  //Assing to it
  ins = &Insert;
  //Same thing
  ins = Insert;

  //Invocation via pointer
  void* ret = (*ins)(pt, pt);

  //Same thing
  ret = ins(pt, pt);

  //Passs the pointer
  create(pt, ins);
}