在C语言中如何提前声明一个结构体

4

如何前向声明以下的treeNodeListCell结构?

我尝试在结构定义之前写struct treeNodeListCell,但代码无法编译。

有人有想法吗?

struct treeNodeListCell;

typedef struct _treeNode {
    treeNodeListCell *next_possible_positions;
} treeNode;

typedef struct _treeNodeListCell {
    treeNode *node;
    struct _treeNodeListCell *next;
} treeNodeListCell;

1
你的实际结构名称是_treeNodeListCell,它被typedef为treeNodeListCell。你确定这不是一个错误吗? - Rahul Bharadwaj
@RahulBharadwaj 嗯,是的,我复制粘贴了我们教授给我们的定义,通常这就是我编写结构体的方式。 - Yaniv Avrahami
敬礼您的教授,他应该阅读 https://dev59.com/KHVC5IYBdhLWcg3woSxW。 - Werner Henze
3个回答

5

你可以前向声明一个结构体,但当你这样做时,你需要使用带有前向声明的结构体标签的 struct 关键字。

struct _treeNodeListCell;

typedef struct _treeNode {
    struct _treeNodeListCell *next_possible_positions;
} treeNode;

typedef struct _treeNodeListCell {
    treeNode *node;
    struct _treeNodeListCell *next;
} treeNodeListCell;

另一种选择是前向声明一个 typedef。C语言允许你用一个不完整的类型来做 typedef,这意味着你可以在定义结构体之前进行 typedef,从而可以在结构体中使用该 typedef

typedef struct _treeNodeListCell treeNodeListCell;

typedef struct _treeNode {
    treeNodeListCell *next_possible_positions;
} treeNode;

struct _treeNodeListCell {
    treeNode *node;
    treeNodeListCell *next;
};

如果你想在不改变结构的情况下使用问题中提到的结构,你只需要在结构定义之前添加typedef即可。
typedef struct _treeNodeListCell treeNodeListCell;

typedef struct _treeNode {
    treeNodeListCell *next_possible_positions;
} treeNode;

typedef struct _treeNodeListCell {
    treeNode *node;
    struct _treeNodeListCell *next;
} treeNodeListCell;

0
快速问题,如何前向声明以下的treeNodeListCell结构体。
你不需要这样做。
首先,你必须区分通过标签识别结构类型和通过typedef定义的别名来识别它们。特别是,你需要明白typedef是完全可选的。当你使用它来定义结构类型的别名时,将typedef声明与结构声明分开可能更清晰。
以下是没有任何typedef的声明:
struct _treeNode {
    struct _treeNodeListCell *next_possible_positions;
};

struct _treeNodeListCell {
    struct _treeNode *node;
    struct _treeNodeListCell *next;
};

使用struct <tag>形式表达的结构类型不需要前向声明。

您也可以添加typedef。通过添加typedef关键字和一个或多个标识符,它们可以与上面的定义相关联,或者可以单独编写,就像我之前推荐的那样:

typedef struct _treeNode treeNode;
typedef struct _treeNodeListCell treeNodeListCell;

个人认为,typedefs 被过度使用了。我通常不会为我的结构体和联合体类型定义 typedef 别名。

但是如果你真的想这样做,那么你可以声明一个未完成的类型的 typedef,比如一个尚未定义的结构体类型。这是一个常规声明,而不是前向声明,但它将允许您在结构体的定义中使用别名,这应该是您的目标:

typedef struct _treeNode treeNode;
typedef struct _treeNodeListCell treeNodeListCell;

struct _treeNode {
    treeNodeListCell *next_possible_positions;
};

struct _treeNodeListCell {
    treeNode *node;
    treeNodeListCell *next;
};

事实上,从C11开始,您可以在同一作用域中写入同一 typedef 名称的多个声明,只要它们都定义了该名称以标识相同的类型。可以利用此规定来允许编译问题中提供的typedef /结构声明。请注意,指定相同类型不需要以相同方式表达该类型。由于这应该是一项练习,我将让您解决剩下的几个细节。

我喜欢你的回答,但问题是我们大学的讲师给了我们这些结构定义,并且他不希望我们改变它们。任务的一部分是找出在结构体之前写什么来使代码正常工作。 - Yaniv Avrahami
@YanivAvrahami,我在结尾处加了一些额外的评论。讲师提出的任务是可以完成的,而这篇答案几乎包含了你所需的所有内容,除了最终答案本身。 - John Bollinger

-2

在 C 语言中,你不能省略 struct

你应该使用

struct treeNodeListCell *next_possible_positions;

替代

treeNodeListCell *next_possible_positions;

只要使用了typedef,就可以省略“struct”关键字。 - Bitmapped

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接