我有3个文件:
-文件1具有table1结构和作用于表2结构的函数
// header file table 1
#include "table_2.h"
typedef struct{...}table1;
void * doSomethingGivenTable2(table2 * t2);
-文件2具有table2结构和作用于表1结构的函数
// header file table 2
#include "table_1.h"
typedef struct{...}table2;
void * doSomethingGivenTable1(table1 * t1);
-文件3使用文件1和2中的两个结构
#include "table_1.h"
#include "table_2.h"
// this is fine because I am including both of them in a separate file
在文件3中发生的事情很好,但是文件1和文件2为结构生成error: unknown type name
,因为我将每个文件的头都包含在另一个文件中。我还定义了使用其他结构的函数。我可以在将两个功能都留在原处的同时解决此问题吗?如果没有,那我有什么选择?
谢谢
答案 0 :(得分:3)
您需要结构标记,以便可以typedef
标识不完整的结构类型。为避免多次定义相同的typedef
标识符,可以将typedef
声明移动到公共头文件中,如下所示:
table_common.h :
#ifndef TABLE_COMMON_H_INCLUDED
#define TABLE_COMMON_H_INCLUDED
typedef struct table1 table1;
typedef struct table2 table2;
#endif
表_1.h :
#ifndef TABLE_1_H_INCLUDED
#define TABLE_1_H_INCLUDED
#include "table_common.h"
struct table1 {
...
};
void * doSomethingGivenTable2(table2 * t2);
#endif
table_2.h :
#ifndef TABLE_2_H_INCLUDED
#define TABLE_2_H_INCLUDED
#include "table_common.h"
struct table2 {
...
};
void * doSomethingGivenTable1(table1 * t1);
#endif
注释:
table1
中的struct table1
是结构标记。我为结构标签及其关联的typedef
标识符使用了相同的名称。可以使用相同的名称,因为结构标记的名称空间不同于其他标识符的名称空间。但是,并不需要结构标记名称与typedef标识符匹配,因此可以根据需要将其更改为其他名称。
我编写的头文件使用一个常见的预处理器技巧来避免多次包含同一头文件时出现问题。为此技巧定义的宏称为“防护宏”。
答案 1 :(得分:2)
您可以像这样将typedef
与实际的struct
定义分开。这使编译器知道table1
是它可以期望找到的数据类型,但是稍后它将获得它的完整定义,因此不必担心它不知道它实际上是什么。 / p>
#ifndef TABLE1_H
#define TABLE1_H
typedef struct table1_s table1;
#include "table2.h"
struct table1_s
{
// contents of struct
};
#endif
顺便说一句,如果您具有仅使用(例如)table2
的函数,则应将它们声明为与table2
相同的包含文件,而不是table1
。< / p>
答案 2 :(得分:1)
也在相反表的标题中声明结构名称,例如
typedef struct table1 table1;
在table2.h内部,反之亦然。
答案 3 :(得分:1)
您需要使用前向声明。
在文件1中,添加以下语句:
typedef struct tbl2 table2;
在文件2中,添加以下语句:
typedef struct tbl1 table1;
在文件3中,添加以下语句:
typedef struct tbl1 table1;
typedef struct tbl2 table2;
这称为前向声明,它告诉您的编译器这些结构在其他位置可用,并且不要抱怨。