当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何在c中的多个文件使用的头中声明一个结构?》经验,为你挑选了3个好方法。

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

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

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

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

或者我应该在头文件中定义了整个结构,包括在两个source.cfunc.c?如何extern在两个文件中声明结构?

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



1> paercebal..:

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

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

正确的方法是将其放在头文件中,并在需要时包含此头文件.

我们应该打开一个新的头文件并在那里声明结构并在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

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

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

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

struct a ;

足够了,它会减少耦合.

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

这是另一种方式,在某种程度上更容易,但模块化程度较低:某些只需要您的结构才能工作的代码仍然必须包含所有类型.

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

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

我也许没有看到这一点,但Greg Hewgill在他的帖子中有一个非常好的答案如何在一个标题中声明一个结构,该结构将由c中的多个文件使用?.

我们应该输入它然后怎么样?

如果您使用的是C++,请不要.

如果你使用C,你应该.

原因是C struct管理可能很麻烦:你必须在使用它的每个地方声明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-ed名称的匿名结构,你将无法向前声明它.所以保持以下格式:

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

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

编辑:

纠正了关于C99结构声明的错误假设,Jonathan Leffler正确地评论道.

编辑2018-06-01:

Craig Barnes在评论中提醒我们,您不需要为struct"tag"名称及其"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单独的"名称空间",使用相同的名称会使阅读更简单.


你能否评论或指出C99标准中保证你"如果你正在使用C99,请不要"评论的部分?
......无论如何,谢谢你的评论.我现在纠正了它.

2> Greg Hewgill..:

对于要在多个源文件中使用的结构定义,您绝对应该将其放在头文件中.然后在任何需要该结构的源文件中包含该头文件.

extern声明不用于结构定义,而是被用于变量声明(即,具有结构式的一些数据值已定义).如果要在多个源文件中使用相同的变量,请将其声明为extern头文件,如:

extern struct a myAValue;

然后,在一个源文件中,定义实际变量:

struct a myAValue;

如果您忘记执行此操作或意外地在两个源文件中定义它,链接器将通知您.



3> fmsf..:

啊:

#ifndef A_H
#define A_H

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

#endif

你去,现在你只需要将ah包含在你想要使用这个结构的文件中.

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有