I am writing a LinkedList in C, the below code represent my Node definition.
我在C中编写LinkedList,下面的代码表示我的Node定义。
typedef struct {
int value;
struct Node* next;
struct Node* prev;
} Node;
I understand (or think that I do) that struct Node
not the same as typedef struct Node
. Granted my code compiles and runs as it's supposed to, however, I get a lot of warnings when assigning next
and prev
(warning: assignment from incompatible pointer type). I am guessing that this has to do with how I'm defining them in the Node structure. I uploaded the full source here
我理解(或者认为我这样做)struct Node与typedef struct Node不同。虽然我的代码编译并按照预期运行,但是,在分配next和prev时会收到很多警告(警告:从不兼容的指针类型分配)。我猜这与我在Node结构中定义它们的方式有关。我在这里上传了完整的资源
So, if that is indeed the problem, how should I define next
and prev
inside the typedef struct Node
?
那么,如果这确实是问题,我应该如何在typedef struct Node中定义next和prev?
I was worried this may be a repost, but couldn't quite find what I was looking for. Thanks.
我担心这可能是一个转贴,但无法找到我想要的东西。谢谢。
2 个解决方案
#1
57
You need to do it in this order:
您需要按此顺序执行此操作:
typedef struct Node Node;
struct Node
{
int value;
Node *next;
Node *prev;
};
That doesn't do exactly what you asked, but it solves the problem and is how this generally is done. I don't think there's a better way.
这并没有完全符合你的要求,但它解决了问题,并且通常是这样做的。我不认为有更好的方法。
This kind of forward declaration has a second usage, in data hiding. If the list was implemented in a library, you could have just the typedef
in the public header, along with functions like:
这种前向声明在数据隐藏方面有第二种用法。如果列表是在库中实现的,那么您可以在公共头中使用typedef,以及以下函数:
Node * list_new(void);
Node * list_append(Node *head, Node *new_tail);
size_t list_length(const Node *head);
This way, users of the library don't have easy access to the internals of your library, i.e. the fields of the Node
structure.
这样,库的用户就无法轻松访问库的内部,即Node结构的字段。
#2
18
Another acceptable way and with the least change to OP's code is the following:
另一种可接受的方式,对OP代码的更改最少如下:
typedef struct NodeT {
int value;
struct NodeT * next;
struct NodeT * prev;
} Node;
Note the introduction of NodeT
and its usage in next
and prev
until Node
is available.
请注意NodeT的介绍及其在next和prev中的用法,直到Node可用。
#1
57
You need to do it in this order:
您需要按此顺序执行此操作:
typedef struct Node Node;
struct Node
{
int value;
Node *next;
Node *prev;
};
That doesn't do exactly what you asked, but it solves the problem and is how this generally is done. I don't think there's a better way.
这并没有完全符合你的要求,但它解决了问题,并且通常是这样做的。我不认为有更好的方法。
This kind of forward declaration has a second usage, in data hiding. If the list was implemented in a library, you could have just the typedef
in the public header, along with functions like:
这种前向声明在数据隐藏方面有第二种用法。如果列表是在库中实现的,那么您可以在公共头中使用typedef,以及以下函数:
Node * list_new(void);
Node * list_append(Node *head, Node *new_tail);
size_t list_length(const Node *head);
This way, users of the library don't have easy access to the internals of your library, i.e. the fields of the Node
structure.
这样,库的用户就无法轻松访问库的内部,即Node结构的字段。
#2
18
Another acceptable way and with the least change to OP's code is the following:
另一种可接受的方式,对OP代码的更改最少如下:
typedef struct NodeT {
int value;
struct NodeT * next;
struct NodeT * prev;
} Node;
Note the introduction of NodeT
and its usage in next
and prev
until Node
is available.
请注意NodeT的介绍及其在next和prev中的用法,直到Node可用。