gpt4 book ai didi

c - 如何在头文件中声明一个结构,该结构将被 c 中的多个文件使用?

转载 作者:太空狗 更新时间:2023-10-29 16:14:41 33 4
gpt4 key购买 nike

如果我有一个带有结构的 source.c 文件:

struct a { 
int i;
struct b {
int j;
}
};

如何在另一个文件(即 func.c)中使用该结构?

我应该创建一个新的头文件,在那里声明结构并将该头文件包含在 func.c 中吗?

或者我应该在头文件中定义整个结构并将其包含在 source.cfunc.c 中吗?如何在两个文件中都将结构声明为 extern

我应该 typedef 吗?如果是,怎么办?

最佳答案

如果这个结构体要被其他文件func.c使用怎么办?

当一个类型在文件中使用时(即 func.c 文件),它必须是可见的。最糟糕的做法是将其复制粘贴到每个需要它的源文件中。

正确的做法是放在头文件中,需要的时候include这个头文件。

我们应该打开一个新的头文件并在那里声明结构并将该头文件包含在 func.c 中吗?

这是我比较喜欢的方案,因为它让代码高度模块化。我会将您的结构编码为:

#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME

struct a
{
int i;
struct b
{
int j;
}
};

#endif

我会将使用此结构的函数放在同一个标​​头中(该函数是其“接口(interface)”的“语义”部分)。

通常,我可以用结构名称命名文件,并再次使用该名称来选择 header 保护定义。

如果您需要使用指向结构的指针来声明函数,则不需要完整的结构定义。一个简单的前向声明,例如:

struct a ;

就足够了,它减少了耦合。

或者我们可以在头文件中定义整个结构并将其包含在 source.c 和 func.c 中吗?

这是另一种方式,更简单一些,但模块化程度较低:一些只需要您的结构即可工作的代码仍然必须包含所有类型。

在 C++ 中,这可能会导致有趣的并发症,但这是题外话(没有 C++ 标记),所以我不会详细说明。

然后如何在两个文件中将该结构声明为 extern。 ?

也许我没明白重点,但 Greg Hewgill 在他的帖子 How to declare a structure in a header that is to be used by multiple files in c? 中有一个很好的答案.

我们可以输入定义吗?

  • 如果您使用的是 C++,请不要使用。
  • 如果您使用的是 C,则应该。

原因是 C 结构管理可能很痛苦:您必须在使用它的任何地方声明 struct 关键字:

struct MyStruct ; /* Forward declaration */

struct MyStruct
{
/* etc. */
} ;

void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}

虽然 typedef 将使您能够在不使用 struct 关键字的情况下编写它。

struct MyStructTag ; /* Forward declaration */

typedef struct MyStructTag
{
/* etc. */
} MyStruct ;

void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}

重要您仍然保留结构的名称是很重要的。写作:

typedef struct
{
/* etc. */
} MyStruct ;

只会创建一个带有 typedef 名称的匿名结构,您将无法转发声明它。所以请保持以下格式:

typedef struct MyStructTag
{
/* etc. */
} MyStruct ;

因此,您可以在任何您想避免添加 struct 关键字的地方使用 MyStruct,并且在 typedef 不起作用时仍然使用 MyStructTag(即前向声明)

编辑:

更正了关于 C99 结构声明的错误假设,正如 Jonathan Leffler 正确指出的那样.

编辑 2018-06-01:

Craig Barnes在他的评论中提醒我们,您不需要为结构“标签”名称及其“typedef”名称保留单独的名称,就像我在上面为清楚起见所做的那样。

事实上,上面的代码完全可以写成:

typedef struct MyStruct
{
/* etc. */
} MyStruct ;

IIRC,这实际上是 C++ 在幕后对其更简单的结构声明所做的,以保持它与 C 的兼容性:

// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;

回到 C,我已经看到了两种用法(单独的名称和相同的名称),而且我知道没有一个有缺点,所以如果您不使用 C separate "namespaces" for structs and other symbols,使用相同的名称会使阅读更简单.

关于c - 如何在头文件中声明一个结构,该结构将被 c 中的多个文件使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/228684/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com