-2

目前我正在使用这个struct

typedef struct node {
    struct node *prev;
    struct node *next;
    size_t elem_size;
    void *data;
} dll_node;

我想使用 2 个指向 and 的指针struct prevnext不用命名structas而是node使用. 我怎样才能做到这一点?dll_nodestruct

我尝试使用

dll_node *next;

而不是当前的,但我收到错误未知类型名称:'dll_node'。

4

5 回答 5

3

做你正在做的事情是不可能的。编译器不知道是什么dll_node,因为它决定了结构在分配时需要的字节数。做这个:

struct node;

typedef struct node dll_node;

struct node {
  dll_node *next;
  dll_node *prev;
  size_t elem_size;
  void *data;
};

...或我个人喜欢使用的方法(因为您经常处理指向结构的指针):

struct node;

typedef struct node *dll_node;

struct node {
  dll_node next;
  dll_node prev;
  size_t elem_size;
  void *data;
};
于 2013-08-11T14:46:40.347 回答
2

避免使用多个标识符来引用同一类型的解决方案是这个习惯用法:

typedef struct dll_node dll_node;

struct dll_node {
  dll_node* prev;
  ...
};

请注意, 的typedef同时作为struct.

另请注意,这仍然在struct名称空间中定义了一个类型名,在标识符名称空间中定义了一个,但这是您在 C 中可以获得的最好的。

于 2013-08-11T15:31:16.357 回答
1
typedef struct node dll_node;

struct node {
dll_node *prev;
dll_node *next;
size_t elem_size;
void *data;
};

如果不事先命名它是不可能的,因为如果最初没有声明它,编译器不知道它是什么。

于 2013-08-11T14:50:33.790 回答
1

C 编译器需要在使用之前查看声明的类型,因为此信息对解析器至关重要。因此,根本不可能在定义名称之前使用类型。

于 2013-08-11T15:19:27.283 回答
0

我真的不明白我是否理解你的观点,但我认为你可以做的是实现一些短的 polymorphic structs。在您的情况下node是标签和dllnode类型。标签是引用结构本身内的结构所必需的,这就是为什么您的最后一条语句失败并且唯一struct node合法的原因。在静态设计中不能有动态行为。所以如果我是你,我会把设计改成这样:

struct dllnode{
    node super;
    dllnode *next;
    dllnode *prev;
    size_t  elem_size;
    void    *payload;
    uint32_t flag;
};

struct node{
   node   *next;
   node   *prev;
   size_t elem_size;
   void   *payload;
};

所以你可以在你的代码中有一个原始类型node和多个“子”类型,dllnode或者你需要的任何其他节点类型!通过将父亲(节点)转换为孩子(dllnode),您可以在两个结构之间交换值。这是因为 C 标准规定结构的第一个成员与结构的开头对齐。例如:

void add_dllnode(struct node *s)
{
    struct dllnode *self = (struct dllnode *) s;
    self->next = s->next;
    self->prev = s->prev;
    self->elem_size = s->elem_size;
    self->payload = s->payload;
    // you can now do treat node as if it's dllnode and probably add it to
    // one of your lists
}

In addition whenever you create a node you can tune the flag member to something like NODE_TYPE_DLL or NODE_TYPE_OTHER and use it as a condition for your invocations, e.g.:

struct node s;
init_node(s);
...
if(((s->flag) & NODE_TYPE_DLL))
    add_dllnode(s);
else
    ...

...
于 2013-08-11T18:04:26.287 回答