我试图打印由head指向的节点的项目,但是最后出现“向不完整类型'struct nodeStruct'错误的引用指针”。 未显示的代码包括list.h文件和该类的其他功能。
相关代码: List.c:
struct nodeStruct {
int item;
struct nodeStruct *next;
};
/*
* Allocate memory for a node of type struct nodeStruct and initialize
* it with the value item. Return a pointer to the new node.
*/
struct nodeStruct* List_createNode(int item) {
struct nodeStruct *newNode = malloc(sizeof(struct nodeStruct));
newNode->item = item;
newNode->next = NULL;
printf("New node created with item %d\n", newNode->item);
return newNode;
}
/*
* Insert node at the head of the list.
*/
void List_insertHead (struct nodeStruct **headRef, struct nodeStruct *node) {
if(*headRef == NULL) {
printf("List is empty, creating new head\n");
*headRef = node;
printf("Empty list new head: %d\n", (*headRef)->item);
}
// Head already exists, shift pointer of head to new node
// and change new head pointer to old head
else {
struct nodeStruct* oldHead = *headRef;
printf("Old head item: %d\n", oldHead->item);
node->next = *headRef;
*headRef = node;
printf("New Head: %d // Old head: %d\n", (*headRef)->item, node->next->item);
}
}
test_list.c:
int main(int argc, char** argv)
{
printf("Starting tests...\n");
struct nodeStruct* head = NULL;
// Create 1 node:
struct nodeStruct* firstNode = List_createNode(0);
List_insertHead(&head, firstNode);
printf("%d\n", head->item); // error
Makefile:
CC=cc
CXX=CC
CCFLAGS= -g -w -std=c99 -Wall -Werror
all: test_list test
# Compile all .c files into .o files
# % matches all (like * in a command)
# $< is the source file (.c file)
%.o : %.c
$(CC) -c $(CCFLAGS) $<
test_list: list.o test_list.o
$(CC) -o test_list list.o test_list.o
test: test_list
./test_list
clean:
rm -f core *.o test_list
打印头的目的是为了查看头是否正常工作。
答案 0 :(得分:2)
您缺少头文件。
C将每个源文件分别编译为目标文件。然后将它们链接在一起。每个.c文件必须知道其使用的所有类型和功能的签名。这意味着list.c
必须知道list.c
中的结构和函数的签名。目前还没有。
您可以将test_list.c
中的#include list.c
直接包含在list.c
中,这实际上会将test_list.c
粘贴到list.c
中。这将起作用,但是其他任何文件都不能使用// list.h
struct nodeStruct {
int item;
struct nodeStruct *next;
};
struct nodeStruct* List_createNode(int);
void List_insertHead (struct nodeStruct **, struct nodeStruct *);
,而不会引起各种问题。
更好的方法是创建一个header file来声明所有类型,并forward declares声明所有函数。前向声明使编译器知道哪些功能可用以及它们的签名是什么,并保证以后还会有其他功能定义该功能。
test_list.c
现在list.c
和#include "list.h"
都可以# Compile list.c into list.o using the declarations in list.h
cc -c -g -w -std=c99 -Wall -Werror list.c
# Compile test_list.c into test_list.o using the declarations in list.h
cc -c -g -w -std=c99 -Wall -Werror test_list.c
# Link both object files into an executable so test_list.o can
# use the functions compiled into list.o
cc -o test_list list.o test_list.o
为编译器提供足够的信息,以将每个源文件编译为目标文件。然后将这些对象链接在一起,并告诉test_list.o在哪里可以找到list.o中的函数。
{{1}}
答案 1 :(得分:1)
您的代码可以正常工作:
查看结果:
Starting tests...
New node created with item 0
List is empty, creating new head
Empty list new head: 0
0
也许与您的编译过程有关。