我是C的新手,有一件事让我发疯是如何让我的项目的所有文件看到一个typedef结构......可能是一个设计错误,不确定......
舞台是我有一个类似这样的typedef结构
// File header.h
typedef struct stu {
char name[60];
char id[10];
int age;
float puntuation;
} Student;
我有几个数据结构,我想使用这个typedef,我有一个堆栈,一个哈希表和一个二叉树...我在main.c中包含所有内容。
// File main.c
#include "header.h"
#include "hashtable.h"
#include "stack.h"
#include "tree.h"
我需要在哈希表和堆栈中使用Student,并且还需要在树中使用堆栈中定义的另一个typedef,但是我无法让它工作......
编译器在tree.h和tree.c中声明类型名称'stack_def'未知,如果我在main.c中排除stack.h并将其包含在tree.h中,那么它在stack.h中对于typedef也是如此学生。
有人可以告诉我这里发生了什么吗?
感谢。
答案 0 :(得分:1)
我的精神力量告诉我你的头文件中有一个循环引用 - 你有两个头文件a.h
和b.h
,其中每个#include
是另一个(或者可能是更长的链,例如a.h
包括b.h
,其中包含c.h
,其中包含a.h
)。
要解决这个问题,您需要删除不必要的内容 - 只有每个头文件都包含正确编译所需的最少其他头文件。如果您只需要使用指向某些类型的指针(没有完整定义),您可以使用前向声明而不是包含类型:
// Forward declaration of `stu' -- we can now use pointers to `stu', but not
// any of the members of `stu' etc.
struct stu;
// Pointer to `stu' -- OK
struct other_struct
{
struct stu *a_pointer;
};
// Function parameters and return value of `stu' -- OK
struct stu function_taking_stu_and_returning_stu(struct stu arg);
// `stu' instance -- ERROR
struct another_struct
{
struct stu not_a_pointer; // ERROR -- `stu' is incomplete
};
从头文件中删除循环依赖项后,它应该正确编译。
答案 1 :(得分:0)
在每个文件中,无论是头文件还是源文件,都使用#include
来包含声明头文件或源文件所需内容的每个头文件。例如,如果tree.h
使用Student
类型,则在tree.h
中放置一个#include
指令,其中包含声明Student
的头文件类型。你不应该猜测这里包含标题。这是一个简单的规则:如果文件使用标头中声明的内容,则将该标头包含在该文件中。
显然,如果每个文件都包含声明文件所需内容的标头,那么文件所需的任何内容都不会被声明。所以那些编译器错误消息应该消失。
执行此操作后,您可能遇到的一个问题是包含循环,其中某些文件包含一个包含第一个文件的标题(可能是间接的,通过一系列包含的文件)。在简单的项目中,不应出现这样的循环;没有标题应该都依赖于声明另一个标题的东西并声明另一个标题需要的东西。但是,如果你有这样一个循环,你可以通过使用所谓的“标题保护”来使第二个包含标题无效,从而打破它:
// Test whether this header has not been included before.
#if !defined ThisHeaderFileName_h
// Define a symbol so we know this header has now been included.
#define ThisHeaderfileName_h
… // Put body of the header file here.
// Close the #if.
#endif