警告:从链表结构中不兼容的指针类型赋值
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
定义为该类型的别名。它不定义其成员next
和prev
指向的类型struct Node
。这不会阻止指向此类类型的指针被声明,但该类型与 Node
不同,并且与其不兼容。
最简单的解决方案,假设其他地方没有 struct Node
的任何定义,就是添加该标记:
typedef struct Node {
int board;
struct Node* next;
struct Node* prev;
}Node;
这就是您的意思。
另请注意,您根本不需要 typedef
。添加标签后,您可以在任何地方将该类型称为 struct Node
。 typedef
' 别名只是一种方便,我认为它被过度使用了。很多时候,typedef
混淆多于帮助。
我收到很多 "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
定义为该类型的别名。它不定义其成员next
和prev
指向的类型struct Node
。这不会阻止指向此类类型的指针被声明,但该类型与 Node
不同,并且与其不兼容。
最简单的解决方案,假设其他地方没有 struct Node
的任何定义,就是添加该标记:
typedef struct Node {
int board;
struct Node* next;
struct Node* prev;
}Node;
这就是您的意思。
另请注意,您根本不需要 typedef
。添加标签后,您可以在任何地方将该类型称为 struct Node
。 typedef
' 别名只是一种方便,我认为它被过度使用了。很多时候,typedef
混淆多于帮助。