我正在尝试用C实现链表。我尝试了以下实现:
// Attempt 1
typedef struct
{
Node *next;
Node *prev;
} Node;
// Attempt 2
typedef struct
{
struct Node *next;
struct Node *prev;
} Node;
第一个版本给了我错误:unknown type name 'Node'
第二个编译但给出警告:assignment to 'struct Node *' from incompatible pointer type 'Node *' {aka 'struct <anonymous> *'}
当我像这样使用它时
void link(Node * node) {
node->next = (Node) {node, NULL}
}
在 typedef 声明中的未命名结构的声明中
typedef struct
{
Node *next;
Node *prev;
} Node;
该名称Node
用作数据成员的类型说明符,next
和prev
是未声明的。因此,编译器会发出错误。
在此声明中,typedef 声明中的未命名结构
typedef struct
{
struct Node *next;
struct Node *prev;
} Node;
引入了类型说明符struct Node
和未命名结构的 typedef 名称Node
。它们是不同的类型说明符。这是Node
,struct Node
不是相同的说明符。
您需要的是以下内容
typedef struct Node
{
struct Node *next;
struct Node *prev;
} Node;
现在Node
是类型说明符struct Node
的别名。
注意这个函数定义
void link(Node * node) {
node->next = (Node) {node, NULL}
}
没有意义,编译器将再次发出错误。 赋值语句的左操作数(忘记放置分号的位置)
node->next = (Node) {node, NULL};
具有类型Node *
或struct Node *
(如果要更新 typedef 声明,如上所示),而右操作数是类型struct Node
的复合文本。此外,复合文字具有自动存储持续时间,退出函数后将不活动。
所以如果你甚至会写
node->next = &(Node) {node, NULL};
退出函数后,指针node->next
将无效。