C 将程序拆分为多个文件-获取错误“;重新定义;不同的基本类型”;

C 将程序拆分为多个文件-获取错误“;重新定义;不同的基本类型”;,c,visual-studio,C,Visual Studio,我想将我的程序分解为多个文件 1. main.c-是主要功能 2. 定义.h-包含#定义、类型定义、功能原型 3. 函数.c-包含函数(definitions.h中的原型) 在definitions.h中,我用typedef表示结构MyStruct,它用于定义.h和函数.c 我已经做了以下工作: 在main.c中,我有#include“definitions.h”和#include“functions.c” 在functions.c中,我有#include“definitions.h” 现在,我

我想将我的程序分解为多个文件
1.
main.c
-是主要功能
2. <代码>定义.h-包含#定义、类型定义、功能原型
3. <代码>函数.c-包含函数(definitions.h中的原型)

在definitions.h中,我用typedef表示结构MyStruct,它用于
定义.h
函数.c

我已经做了以下工作:

main.c
中,我有
#include“definitions.h”
#include“functions.c”

functions.c
中,我有
#include“definitions.h”

现在,我得到了错误
C2371:'MyStruct':重新定义;不同的基本类型
(它是visual Studio)

现在,我不明白为什么我会出现这个错误! 谢谢


所以你建议做以下几点

main.c
put
#包含“definitions.h”
(带有typedef和#define&function标题)

现在,我如何告诉编译器需要查看
functions.c
文件中的函数定义 我应该把
#include“functions.c”
放入
definitions.h
文件吗


谢谢

首先-您不必在
main.c
中包含“functions.c”-定义已经存在于
definitions.h
中。一般来说,应该避免包含另一个源文件

第二,您的
定义.h
文件中可能没有
#include
-guard,这会导致此问题,因为您在
main.c
中同时包含
函数.c
定义.h
,并且
函数.c
也包含
定义.h
,这将导致多重定义的疯狂

/* include guards */
#ifndef definitions_h_
#define definitions_h_
/* all of definitions.h content */
#endif
编辑


此外,根据您使用的编译器,您可能可以使用simpler指令。VC++支持它,就像GCC的最近版本(3.4)。

第一,你不必在<代码>主目录。C < /COD>中包含“函数C。”/>代码>定义已经存在于<代码>定义。一般来说,应该避免包含另一个源文件

第二,您的
定义.h
文件中可能没有
#include
-guard,这会导致此问题,因为您在
main.c
中同时包含
函数.c
定义.h
,并且
函数.c
也包含
定义.h
,这将导致多重定义的疯狂

/* include guards */
#ifndef definitions_h_
#define definitions_h_
/* all of definitions.h content */
#endif
编辑


此外,根据您使用的编译器,您可能可以使用simpler指令。VisualC++支持它,就像GCC的最近版本(3.4)。

< P>你的第一个问题是,正如我的评论所建议的,你包含一个源文件。您只包含头文件,这样原型就在那里,代码就可以编译了,但不包括其他代码文件——这些文件是单独编译的。不这样做会破坏单独编译的唯一优势,即更快的重新编译,因为每次编译之间只有少数源文件发生更改,并且不需要再次编译未更改的文件,因为.obj文件仍然存在

解决了这个问题,你的问题就会消失。但不是永远,只要项目保持那么小,并且不多次包含任何内容。每个头文件(好吧,包括的每个文件-但这只是头文件)都必须有一个“包含保护”,防止文件被多次包含(请记住,
#包含“文件”
仅表示“在编译之前将
文件的内容粘贴到此处”)-
main.c
包括
定义.h
函数.c
,但
函数.c
也包括
定义.h
,因此
定义.h
的内容包含两次,因此所有类型和函数原型实际上都定义了两次-这是非法的。在每个头文件的最开始处,放置如下内容:

#ifndef UNIQUE_HEADER_NAME_H
#define UNIQUE_HEADER_NAME_H

最后,在endif后面加一个
#endif
(有些人更喜欢
#endif//UNIQUE_HEADER_NAME_H
,以便澄清)。因此,当文件第一次包含时,
UNIQUE\u HEADER\u NAME\u H
未定义,因此文件将作为普通文件包含,而
UNIQUE\u HEADER\u NAME\u H
将被定义。下一次包含它时,已经定义了
唯一的\u头\u名称\u H
,因此预处理器会跳到匹配的endif(末尾的endif,除非在实际的头中遗漏了一个),并且不会两次包含任何内容。

正如我在评论中所建议的,您的第一个问题是,您包含了一个源文件。您只包含头文件,这样原型就在那里,代码就可以编译了,但不包括其他代码文件——这些文件是单独编译的。不这样做会破坏单独编译的唯一优势,即更快的重新编译,因为每次编译之间只有少数源文件发生更改,并且不需要再次编译未更改的文件,因为.obj文件仍然存在

解决了这个问题,你的问题就会消失。但不是永远,只要项目保持那么小,并且不多次包含任何内容。每个头文件(好吧,包括的每个文件-但这只是头文件)都必须有一个“包含保护”,防止文件被多次包含(请记住,
#包含“文件”
仅表示“在编译之前将
文件的内容粘贴到此处”)-
main.c
包括
定义.h
函数.c
,但
函数.c
也包括
定义.h
,因此
定义.h
的内容被包括两次,因此所有类型和函数