警告:从链表结构中不兼容的指针类型赋值

Warning: assignment from incompatible pointer type in linked list struct

我收到很多 "assignment from incompatible pointer type" 警告,但我不知道为什么。 这部分出现的警告:

void addNode(linkedList* list, int board)
{
Node* newNode = createNode(board);
(list->last)->next = newNode; // this line has warning
newNode->prev = list->last; // this line has warning
}

结构和其余代码是:

typedef struct{
    int board;
    struct Node* next;
    struct Node* prev;
}Node;

typedef struct{
    int length;
    Node* first;
    Node* last;
}linkedList;

Node* createNode(int board)
{
    Node* node = (Node*)malloc(sizeof(Node));
    node->next = NULL;
    node->prev = NULL;
    node->board = board;
    return node;
}
linkedList* createList()
{
    linkedList* list = (linkedList*)malloc(sizeof(linkedList));
    list->first = NULL;
    list->last = NULL;
    list->length = 0;
    return list;
 }

您从未真正定义 struct Node

您将 (typedef) 别名为 Node 的类型是未标记的 struct。当您稍后声明指针 struct Node* 时,编译器允许它作为指向不完整类型(隐式声明)的指针,但这与程序中声明的任何类型都不相同。

用自引用指针声明结构的一个好方法是:

typedef struct Node Node;
struct Node {
    int board;
    Node* next;
    Node* prev;
};

在该表述中,第一行将 Node 定义为仍然不完整的类型 struct Node 的别名,然后由第二个声明定义。当遇到Node*成员声明时struct Node仍然不完整,但允许指向不完整类型的指针。

我喜欢这种风格的一个原因是它适用于 struct 是一种不透明数据类型的常见情况,其成员不打算供 public 使用。在这种情况下,typedef 可以放在头文件中,允许指向不透明类型的指针在函数原型中使用或用作局部变量。 struct 定义本身然后进入实现。

这个...

typedef struct{
    int board;
    struct Node* next;
    struct Node* prev;
}Node;

... 声明无标记结构类型,并将 Node 定义为该类型的别名。它定义其成员nextprev指向的类型struct Node。这不会阻止指向此类类型的指针被声明,但该类型与 Node 不同,并且与其不兼容。

最简单的解决方案,假设其他地方没有 struct Node 的任何定义,就是添加该标记:

typedef struct Node {
    int board;
    struct Node* next;
    struct Node* prev;
}Node;

这就是您的意思。

另请注意,您根本不需要 typedef。添加标签后,您可以在任何地方将该类型称为 struct Nodetypedef' 别名只是一种方便,我认为它被过度使用了。很多时候,typedef混淆多于帮助。