功能指针 - 存储和使用

时间:2014-09-13 01:57:08

标签: c list function-pointers

我有一个链表,每个元素都可以包含

typedef struct elem {
    struct elem *next;
    void *data;
} *elem;

现在,说我有一个类似......的方法。

void blah(int random) {
    printf("testing\n");
}

我将它存储在我的列表中......

elem lst = (elem) malloc(sizeof(elem));
lst->next = NULL;
lst->data = &blah;

我现在如何通过链接列表中的方法调用该方法? 此外,我是否正确地将该功能存储在我的链表中?

4 个答案:

答案 0 :(得分:4)

更好:

typedef void (*blah_ptr)(int);
...
typedef struct elem {
    struct elem *next;
    blah_ptr data;
} *elem;
...
lst->data = blah;

完整的示例可能有所帮助:

#include <stdio.h>

typedef void (*blah_ptr)(int);

typedef struct elem {
    struct elem *next;
    blah_ptr data;
} *elem;

void blah (int random) {
  printf ("We're in blah: random=%d...\n", random);
}

void bleep (int nonrandom) {
  printf ("We're in bleep: nonrandom=%d...\n", nonrandom);
}

int
main (int argc, char *argv[]) {

  struct elem lst[2];

  lst[0].next = &lst[1];
  lst[0].data = blah;
  lst[1].next = NULL;
  lst[1].data = bleep;

  lst[0].data(10);
  lst[1].data(20);

  return 0;
}

这是输出:

We're in blah: random=10...
We're in bleep: nonrandom=20...

答案 1 :(得分:3)

C标准不允许您将函数指针强制转换为void*。为了将函数指针存储在列表中,您需要在struct中定义一个字段作为函数指针类型。

一种方法是使用typedef

typedef void (*fptr_int)(int); // This defines a type fptr_int

现在您可以在struct中使用它,如下所示:

typedef struct elem {
    struct elem *next;
    fptr_int *function;
} *elem;

按照您在示例中的方式进行分配:

lst->function = &blah;

将其称为函数名称:

lst->function(123);

typedef不需要特定于您要存储的函数的签名,但是:任何函数指针都可以转换为另一个函数指针并返回而不会出现错误。你可以定义一个&#34;泛型&#34;函数指针,像这样

typedef void (*void_fptr)();

struct

中使用它
typedef struct elem {
    struct elem *next;
    void_fptr *function;
} *elem;

并使用适当的演员阵容:

lst->function = (void_fptr)&blah; // Assign
...
((fptr_int)lst->function)(123);   // Call

答案 2 :(得分:2)

我不想回答其他人已经提出的问题,比如dasblinkenlight,但我想对结构和类型的定义方式以及引入的好奇malloc错误进行观察。

您定义了类型*elem。如果你要调用sizeof(elem),它将返回指向数据的指针的大小 - 而不是数据结构本身的大小。在您的情况下,您通过malloc分配太少的字节,这可能导致堆的内存损坏。我已经对自己进行了观察,认为代码有点难以阅读作为副作用。特别是这一行

elem lst = (elem) malloc(sizeof(elem));

我的第一个想法是,elem是一个结构,而不是指向结构的指针。通常当人们创建结构时,他们会这样做:

typedef struct _elem {
    struct elem *next;
    void (*data)();
} elem;

注意elem没有被定义为指针类型。然后malloc看起来像:

elem *lst = (elem*) malloc(sizeof(elem));

现在我很清楚你正在处理指向元素的指针。同样sizeof(elem)现在将是elem数据结构的大小,而不是指向数据结构的指针的大小elem

如果您保持数据结构的替代方法是以这种方式执行malloc

elem lst = (elem) malloc(sizeof(*lst));

lst已被定义为elem(这是一个指针)。然后使用*lst取消引用指针,告诉sizeof你想要指向的大小(因此elem的大小)。

答案 3 :(得分:1)

typedef void (*fptr)(int);
((fptr)lst->data)(42);
相关问题