如何在c中的多个文件使用的头文件中声明一个结构? [英] How to declare a structure in a header that is to be used by multiple files in c?

查看:33
本文介绍了如何在c中的多个文件使用的头文件中声明一个结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If I have a source.c file with a struct:

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

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

How can this struct be used in another file (i.e. func.c)?

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

Should I create a new header file, declare the struct there and include that header in func.c?

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

Or should I define the whole struct in a header file and include that in both source.c and func.c? How can the struct be declared extern in both files?

我应该typedef吗?如果有,怎么做?

Should I typedef it? If so, how?

推荐答案

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

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

if this structure is to be used by some other file func.c how to do it?

When a type is used in a file (i.e. func.c file), it must be visible. The very worst way to do it is copy paste it in each source file needed it.

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

The right way is putting it in an header file, and include this header file whenever needed.

这是我更喜欢的解决方案,因为它使代码高度模块化.我会将您的结构编码为:

This is the solution I like more, because it makes the code highly modular. I would code your struct as:

#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME

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

#endif

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

I would put functions using this structure in the same header (the function that are "semantically" part of its "interface").

通常,我可以在结构名称之后命名文件,然后再次使用该名称来选择标题保护定义.

And usually, I could name the file after the structure name, and use that name again to choose the header guards defines.

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

If you need to declare a function using a pointer to the struct, you won't need the full struct definition. A simple forward declaration like:

struct a ;

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

Will be enough, and it decreases coupling.

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

This is another way, easier somewhat, but less modular: Some code needing only your structure to work would still have to include all types.

在 C++ 中,这可能会导致一些有趣的复杂情况,但这是题外话(没有 C++ 标签),所以我不会详细说明.

In C++, this could lead to interesting complication, but this is out of topic (no C++ tag), so I won't elaborate.

也许我没明白这一点,但 Greg Hewgill 在他的帖子中给出了一个很好的答案 如何在 c 中的多个文件使用的头中声明结构?.

I fail to see the point, perhaps, but Greg Hewgill has a very good answer in his post How to declare a structure in a header that is to be used by multiple files in c?.

  • 如果您使用的是 C++,请不要.
  • 如果您使用的是 C,则应该这样做.

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

The reason being that C struct managing can be a pain: You have to declare the struct keyword everywhere it is used:

struct MyStruct ; /* Forward declaration */

struct MyStruct
{
   /* etc. */
} ;

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

虽然 typedef 可以让您在没有 struct 关键字的情况下编写它.

While a typedef will enable you to write it without the struct keyword.

struct MyStructTag ; /* Forward declaration */

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

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

重要您仍然保留结构的名称.写作:

It is important you still keep a name for the struct. Writing:

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

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

will just create an anonymous struct with a typedef-ed name, and you won't be able to forward-declare it. So keep to the following format:

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

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

Thus, you'll be able to use MyStruct everywhere you want to avoid adding the struct keyword, and still use MyStructTag when a typedef won't work (i.e. forward declaration)

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

Corrected wrong assumption about C99 struct declaration, as rightfully remarked by Jonathan Leffler.

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

Craig Barnes reminds us in his comment that you don't need to keep separate names for the struct "tag" name and its "typedef" name, like I did above for the sake of clarity.

确实,上面的代码可以写成:

Indeed, the code above could well be written as:

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

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

IIRC, this is actually what C++ does with its simpler struct declaration, behind the scenes, to keep it compatible with C:

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

回到 C,我已经看到了这两种用法(单独的名称和相同的名称),并且没有一个有我所知道的缺点,所以如果你不使用 C 分离命名空间"用于结构和其他符号.

Back to C, I've seen both usages (separate names and same names), and none has drawbacks I know of, so using the same name makes reading simpler if you don't use C separate "namespaces" for structs and other symbols.

这篇关于如何在c中的多个文件使用的头文件中声明一个结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆