C 指向不完整类型的循环结构指针

C 指向不完整类型的循环结构指针,c,struct,C,Struct,因此,我正在实现我自己的链表,以尝试使用单独的头文件和源文件编译项目。我为定义创建了一个LinkedList.h,为实现创建了一个LinkedList.c 我发现post在typedefvsstruct方面提供了大量信息,并告知我编译器正在抱怨不知道头文件中的定义(可能?) 如果我移动对象,我最终会出现错误,struct Node{…}中没有定义Node,即使是向前声明的typedef struct Node 如果我需要补充什么,请告诉我 首先出错: You have to put the st

因此,我正在实现我自己的链表,以尝试使用单独的头文件和源文件编译项目。我为定义创建了一个
LinkedList.h
,为实现创建了一个
LinkedList.c

我发现post在
typedef
vs
struct
方面提供了大量信息,并告知我编译器正在抱怨不知道头文件中的定义(可能?)

如果我移动对象,我最终会出现错误,
struct Node{…}
中没有定义
Node
,即使是向前声明的
typedef struct Node

如果我需要补充什么,请告诉我

首先出错:

You have to put the structure definitions in the header file, not the code file, so that 
main.c
can refer to the members.

You don't need to use
typedef
when defining the structure, that will create a duplicate typedef. Just do a forward definition of the type, and define the structure without
typedef
.

typedef struct Node Node;
struct Node {
  unsigned long value;
  Node *next;
};

typedef struct LinkedList LinkedList;
struct LinkedList {
  unsigned long length;
  Node *head;
  Node *tail;
};

Node* CreateNode(unsigned long);
LinkedList* CreateList();
void addTail(LinkedList*, Node*);
LinkedList* CreateList();

您必须将结构定义放在头文件中,而不是放在代码文件中,以便
main.c
可以引用成员

定义结构时不需要使用
typedef
,这将创建重复的typedef。只需对类型进行正向定义,并在不使用
typedef
的情况下定义结构即可

Main: Main.o LinkedList.o
    gcc -o Main Main.o LinkedList.o
“未定义引用”问题是因为您没有在Makefile中正确编译。
Main
的规则应该是:

Node *nextNode(Node*)

请参见

一个更好的选择是添加

到您的头文件,并使用它来迭代列表

之后,考虑使用<代码>列表*CREATELIST()>代码>为根节点指针设置一个位置。当您使用

removeNode()


更新:要访问节点的值,请尝试添加
无符号长getValue(节点*节点)
。考虑API试图隐藏API后面的实现细节(例如一个同样适用于可调整数组、双链表和单链表的API)的形式。

您需要将结构声明放在 Link KeList.H./C>中,而不只是在<代码> LIKEDLIST.C/<代码>中。否则,
main.c
无法访问成员。让我们仔细查看LinkedList.h。没有人能在那里看到
head
value
,而且在解析Main.c时,编译器也找不到它们。用答案修改问题不是一个好主意。如果你想回答自己的问题,请在下面贴出答案。Quesiton回滚了。这实际上是最佳建议-它保持整洁地隐藏列表的实现细节!这仍然无助于打印
runner->value
@Barmar您是对的,因此答案并不完整。它显示了去的特质,但是…解释得很好。对于解决方案,我更倾向于Arkadiy,因为它可以防止暴露列表实现的内部。这样就消除了我的取消引用指针错误,但现在我得到了对
CreateList、CreateNode和addTail的
未定义引用。知道原因吗?您需要将所有函数声明放在头文件中。您应该只在
CreateList
中得到该错误,因为头文件中缺少该错误。我看不出其他函数会出现错误的任何原因。@MichaelBeer如果要避免暴露内部,还需要添加一个
getValue()
函数,这样就不需要使用
runner->value