打印链接列表中标题所指向的项目时出现取消引用错误

时间:2018-09-23 03:10:53

标签: c pointers linked-list

我试图打印由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

打印头的目的是为了查看头是否正常工作。

2 个答案:

答案 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

也许与您的编译过程有关。