转发" Typedefing"结构

时间:2016-03-15 05:56:34

标签: c typedef forward-declaration

我的包含文件存在轻微问题,我已经对我的问题进行了简化的模拟。 假设我正在编译一些需要名为

的头文件的源代码
header.h

其中包含:

#ifndef HEADER_INCLUDED
#define HEADER_INCLUDED

#include element.h
typedef struct {
    Element *list;
} Thing;

#endif

然后我有另一个头文件定义该元素并且还需要header.h。

element.h

#ifndef ELEMENT_INCLUDED
#define ELEMENT_INCLUDED

typedef struct Element;

#include header.h
void * func(Thing *myThing);

#endif

然后我遇到了一个问题,因为element.h不知道Thing类型是什么;我们还没有在header.h中达到那个定义,因为我们需要包含element.h。

我想我可以解决我的问题&#34; forward typedefing&#34; element.h中的Thing类型,就像<* p>之类的void * func原型之前

typedef struct thing Thing;

然后这就产生了另一个问题,并且编译器抱怨Thing存在冲突的类型。

如何摆脱这种混乱?

4 个答案:

答案 0 :(得分:1)

你的主要问题是2之间存在循环依赖关系,但你正在使用防护宏。这些文件几乎就像复制粘贴一样 - 其中一个文件必须先包含在另一个文件中,因此您不能拥有这样的循环依赖。重新思考你的结构。

在一个位置声明/定义基本数据类型,然后使用它来定义派生/复合数据类型,最后是将这些类型作为参数/返回值的函数。

此外,typedef struct Element;是无效的typedef。

答案 1 :(得分:0)

解决问题的最简单方法是将结构定义隔离在自己的标头中,并像往常一样受#ifndef / #define保护。如果你不想要这个单一结构的头文件,那么定义结构两次并用另一种#ifndef / #def以这种方式保护它的定义:

#ifndef __BOOLEAN_ENUM__
#define __BOOLEAN_ENUM__
enum boolean
{
    false = 0,
    true = 1
};
#endif

答案 2 :(得分:0)

header.h不应包含element.h。否则你有循环依赖。

您发布的代码存在大量错误。 (将来,您尝试编译的实际代码,而不是在编辑框中编写内容)。这是一个例子,我为了简洁省略了标题保护:

// header.h
struct Element;       // actually not necessary, but may help with readability

typedef struct
{
    struct Element *ptr;
} Thing;

// element.h
#include "header.h"

struct Element
{ 
    int x;
};

typedef struct Element Element;   // optional

void * func(Thing *myThing);

也可以在typedef struct Element Element;中放置header.h并在Element *ptr的定义中使用Thing,这是您喜欢哪种方式的品味问题。有些人不赞成在C语言中使用typedef结构,但是我喜欢它,因为它意味着拼写错误导致立即编译错误,而不是默默地创建新类型。

如果您还希望element.h不依赖header.h,则可以对Thing使用相同的技巧。你需要给它一个struct标签,就像struct Element的方式一样。

答案 3 :(得分:0)

退出C代码和整个程序设计的事情。

很明显,&#34; Thing&#34; struct必须依赖于&#34;元素&#34; element.h中的struct。但是,使用依赖于&#34; Thing&#34;的功能并没有任何意义。从元素标题内部。最有意义的是使用&#34; Thing&#34;应该在&#34; Thing&#34;报头中。

如果你使用面向对象的方法来看待它,你应该不管编程语言,那么Element就是一个类,Thing是一个类。该函数可以是Thing的成员函数,也可以是使用该类的非相关函数。

你在面向对象的C中做的是宣告&#34;元素&#34;和&#34;事情&#34;在各自的标题中作为不完整类型。类型定义对调用者是隐藏的,并且仅存在于那些头的相应C文件中,称为element.c和thing.c。处理各个类的所有成员函数将在头文件中声明并在C文件中定义。 (此设计有时也称为 opaque类型或不透明指针。)

使用任一类的函数将只包含所需的标题。