【问题标题】:recursive type definitions in C [duplicate]C中的递归类型定义
【发布时间】:2021-07-10 22:13:58
【问题描述】:

我正在尝试在 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}
}

【问题讨论】:

  • (Node) {node, NULL} 应该是 (Node*)&{node, NULL},因为 next 是一个指针。
  • 将您的 Attempt 2 更改为 typedef struct Node {...} Node;
  • 但是,这将是无效的,因为复合字面量返回一个指向本地数据的指针。
  • 尤金什。说或者你也可以做typedef struct Node; struct Node { Node *next,*prev; };

标签: c struct linked-list declaration typedef


【解决方案1】:

在 typedef 声明中的未命名结构的此声明中

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

用作数据成员 nextprev 的类型说明符的名称 Node 未声明。所以编译器会报错。

在此声明中的未命名结构的 typedef 声明

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

为未命名的结构引入了类型说明符struct Node 和类型定义名称Node。它们是不同的类型说明符。也就是说Nodestruct 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将失效。

【讨论】:

  • 也可以先声明类型:typedef struct Node Node;,然后在结构体定义中使用新类型:struct Node { Node *next; Node *prev; };
猜你喜欢
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多