1

我在 C 中有一个问题,我不知道如何解决。假设我有 4 个 c 文件,ac;公元前; 抄送; dc,每一个都有一个.h文件:啊;bh; ch; dh,当然也包括在内。我想做以下事情:

啊将包含:

#include "b.h"
#include "c.h"
...

bh 将包含:

#include "d.h"
...

和 ch 还将包含:

#include "d.h"
...

在 dh 我定义了一个结构,例如, dh 的内容将是:

typedef struct address { 
   int address; 
} address;

问题是我得到错误(当我编译文件时):

In file included from c.h:1:0,
                 from a.h:2,
                 from a.c:1:
d.h:3:16: error: redefinition of ‘struct address’
d.h:3:16: note: originally defined here
d.h:5:3: error: conflicting types for ‘address’
d.h:5:3: note: previous declaration of ‘address’ was here

我明白为什么会这样(因为 preproccesor 两次导入定义),但我该如何解决呢?我需要包含这样的方式(因为我当然有更多文件,这只是一个例子)。我能做些什么?

注意:我的makefile是:

project: a.o b.o c.o d.o
    gcc -g a.o b.o c.o d.o -ansi -Wall -pedantic -o output

a.o: a.c a.h  b.c b.h c.c c.h d.c d.h 
    gcc -c a.c -ansi -Wall -pedantic -o a.o

b.o: b.c b.h d.c d.h
    gcc -c b.c -ansi -Wall -pedantic -o b.o

c.o: c.c c.h d.c d.h
    gcc -c c.c -ansi -Wall -pedantic -o c.o

d.o: d.c d.h
    gcc -c d.c -ansi -Wall -pedantic -o d.o

我认为没关系..它对我有用。感谢您的帮助。

4

3 回答 3

3

将每个头文件的内容包含在预处理器守卫中:

/* a.h */
#ifndef A_H_
#define A_H_

/* content of a.h goes here */

#endif

其他标题相同:

/* b.h */
#ifndef B_H_
#define B_H_

/* content of b.h goes here */

#endif

等等。

这是确保每个标题内容只读一次的常用方法。(第一次读取文件时,符号[eg B_H_]尚未定义,所以ifndef为真,读取内容。从第二次开始,定义符号,跳过内容。

请注意,符号的名称A_H_是任意的,但通常人们使用大写字母的标题名称。因此,只要您包含两个具有相同名称的不同标头,该机制就会失败,除非您为守卫使用不同的名称。

您可能还想在谷歌上搜索#pragma once,许多预处理器都支持,但这不是标准的。

于 2013-08-13T13:46:26.747 回答
0

添加一次性标题。有关更多信息,请参阅以下链接。

http://gcc.gnu.org/onlinedocs/cpp/Once_002dOnly-Headers.html#Once_002dOnly-Headers

于 2013-08-13T13:53:59.073 回答
0

您可以使用“includeguards”来防止预处理器将头文件的内容多次放入预处理的源代码中。

使用

#ifndef A_H_
#define A_H_

您定义了一个名为A_H_. 如果预处理器再次命中该符号,它将忽略介于两者之间的内容

#ifndef A_H_
#define A_H_

#endif

还有特定的编译器命令,例如#pragma once,这适用于 Visual Studio,并且与 include-guards 的作用相同。检查你的编译器是否提供了这样的东西。

于 2013-08-13T13:48:44.117 回答