如何在c中的多个文件使用的头中声明结构?

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

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

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

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

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

我应该typedef它吗? 如果是这样,怎么样?

如果这个结构被其他文件func.c使用,怎么做?

当一个types被用于一个文件(即func.c文件)时,它必须是可见的。 最糟糕的方法是复制粘贴到每个需要它的源文件中。

正确的方法是把它放在一个头文件中,并在需要时包含这个头文件。

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

这是我更喜欢的解决scheme,因为它使代码高度模块化。 我会编码你的结构为:

 #ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME #define SOME_HEADER_GUARD_WITH_UNIQUE_NAME struct a { int i; struct b { int j; } }; #endif 

我会把使用这个结构的函数放在同一个头文件中(这个函数是“接口”的“语义”部分)。

通常,我可以在结构名称后面命名该文件,并再次使用该名称来select标题防护定义。

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

 struct a ; 

将是足够的,并减less耦合。

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

这是另一种方式,更容易一些,但较less模块化:一些代码只需要你的结构工作将仍然必须包括所有types。

在C ++中,这可能会导致一些有趣的复杂性,但是这不是主题(没有C ++标记),所以我不会详细说明。

那么如何在这两个文件中声明该结构为extern。 ?

也许我没有看到这一点,但是Greg Hewgill在他的文章中有一个很好的答案。 如何在c中的多个文件使用的头文件中声明一个结构? 。

我们应该怎样打字呢?

  • 如果你使用C ++,不要。
  • 如果你使用C,你应该。

原因是C结构pipe理可能是一个痛苦:你必须在使用它的地方声明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 ; 

只会创build一个带有typedef-name名字的匿名结构,而且你将无法转发 – 声明它。 所以请保持以下格式:

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

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

编辑:

纠正了关于C99结构声明的错误假设,正如Jonathan Leffler所说的。

对于要在多个源文件中使用的结构定义,您一定要把它放在一个头文件中。 然后将该头文件包含在任何需要该结构的源文件中。

extern声明不是用于结构定义,而是用于variables声明(也就是说,一些具有您定义的结构types的数据值)。 如果你想在多个源文件中使用相同的variables,在头文件中声明它为extern

 extern struct a myAValue; 

然后,在一个源文件中,定义实际的variables:

 struct a myAValue; 

如果您忘记这么做或者意外地将其定义在两个源文件中,链接程序会通知您。

啊:

 #ifndef A_H #define A_H struct a { int i; struct b { int j; } }; #endif 

现在你去了,现在你只需要在你想要使用这个结构的文件中包含啊。