C 有没有一种方法可以在结构内部使用指向结构的指针而不命名结构?

C 有没有一种方法可以在结构内部使用指向结构的指针而不命名结构?,c,struct,C,Struct,目前我正在使用这个struct typedef struct node { struct node *prev; struct node *next; size_t elem_size; void *data; } dll_node; 我想使用两个指向structprev和next的指针,而不将struct命名为节点,而是在struct内部使用typedefdll\u节点。我该怎么做 我试着用 dll_node *next; 而不是当前的,但我得到的错误是未知

目前我正在使用这个
struct

typedef struct node {
    struct node *prev;
    struct node *next;
    size_t elem_size;
    void *data;
} dll_node;
我想使用两个指向
struct
prev
next
的指针,而不将
struct
命名为
节点
,而是在
struct
内部使用typedef
dll\u节点
。我该怎么做

我试着用

dll_node *next;

而不是当前的,但我得到的错误是未知类型名称:“dll\u node”。

无法执行您正在执行的操作。编译器不知道什么是
dll\u节点
,因为它决定了结构在分配时所需的字节数。这样做:

struct node;

typedef struct node dll_node;

struct node {
  dll_node *next;
  dll_node *prev;
  size_t elem_size;
  void *data;
};
。。。或者我个人喜欢使用的方法(因为您经常处理指向结构的指针):


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

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

避免使用多个标识符来引用同一类型的解决方案如下:

typedef struct dll_node dll_node;

struct dll_node {
  dll_node* prev;
  ...
};
请注意,
typedef
同时充当
struct
的前向声明

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

还要注意的是,这仍然在
struct
名称空间中定义了一个typename,在标识符名称空间中定义了一个typename,但这是在C中可以得到的最好结果。

如果我理解了你的观点,我真的不太明白,但我认为你可以做的是实现一些多态
struct
s。在您的例子中,
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;
};
因此,您可以在代码中包含一个基本类型
节点
,以及多个“子”类型,如
dllnode
或您需要的任何其他节点类型!通过将父节点(node)转换为子节点(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
}
此外,无论何时创建
节点
,都可以将标志成员调整为类似
节点类型_DLL
节点类型_其他
的值,并将其用作调用的条件,例如:

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

...

我想知道是否有可能做到这一点,而不事先命名。你说的。@A大使馆不,这不是建设性的批评:解释否决票,这样我下次可以问更好的问题不是我的否决票,但也许你可以激发你的问题?@JensGustedt没有理解你。你所说的激励是什么意思?如果标识符的“浪费”是困扰你的问题,那么在转发声明中,你可以对
struct
typedef
使用相同的标识符。为什么不给
struct
命名呢?对我来说,这听起来不是一个很有用的限制。
struct node s;
init_node(s);
...
if(((s->flag) & NODE_TYPE_DLL))
    add_dllnode(s);
else
    ...

...