我在C语言中有一个关于包含头文件的奇怪问题。
c
#include <stdio.h>
#include <stdlib.h>
#include "location.h"
int waste_new_line();
int main()
{
location *crossroads = malloc(sizeof(*crossroads));
...
location.h
typedef struct Location_Struct location;
location.c
typedef struct Location_Struct {
int ID;
char *name;
char *description;
} location;
int setup_location(location* l, char* name)
{
...
现在不起作用了,因为
location *crossroads = malloc(sizeof(*crossroads));
抛出一个指向不完整类型的解引用指针错误,这意味着它可以看到location.h的内容,但它似乎不知道location.c…
我看了一下,我看到的所有教程都说链接器会把两个文件链接在一起。
编辑:我修改了代码,在location.c中包含一个初始化器,如下所示:
c
...
#include "location.h"
int waste_new_line();
int main()
{
location *crossroads = initialize_location();
....
location.h
typedef struct Location_Struct location;
location* initialize_location();
location.c
...
typedef struct Location_Struct {
int ID;
char *name;
char *description;
} location;
location* initialize_location(location* l)
{
return malloc(sizeof(location));
}
...
这仍然抛出相同的错误,但只有当我尝试使用:
访问crossroads的成员时才会抛出相同的错误:crossroads->description
这会抛出不完整类型错误。
编辑2:现在我决定只是把结构体定义在头文件…
这种行为是预期的。当您使用#include "location.h"
时,只有头文件对编译器可见。location.c
文件稍后在链接时出现。
你有两个选择:
- 添加一个函数,在
location.h
中声明并在location.c
中定义,它执行必要的malloc
并返回一个指针。 - 将结构体的完整定义移动到头文件中。
main
文件知道一个名为Location_Struct
的struct
(和一个typedef)。它不知道它有多大,因此你不能对它应用sizeof
。
既然你有效地隐藏了布局和Location_Struct
的实现,那么提供一个"构造器"是有意义的。
编辑
似乎我必须提到"构造器"我的意思是一个普通的函数,它可以访问结构的实现,可以分配和可能的预填充对象。
您需要将Location_Struct
的定义放在头文件location.h中。编译器不会"看到"另一个源文件(除非它是#include,这通常不是一个好主意)。