在C语言头文件中使用define

5

我刚开始学习C语言,所以希望这不是一个愚蠢的问题。我遇到的问题与头文件和使用#define定义常量有关。我已经阅读过应该使用以下内容来防止我的头文件被编译多次。

#ifndef NAME_OF_FILE
#define NAME_OF_FILE
.
. //my header file content
.
#endif

我希望你能加入一个常量,我认为我也可以使用#define,比如说:
#ifndef NAME_OF_FILE
#define NAME_OF_FILE

#define NUM_CONST 5 //the constant I want in my header file
.
.
.
#endif

C语言是如何知道#define NAME_OF_FILE指的是.h文件,而#define NUM_CONST 5仅仅是一个常量?是因为NUM_CONST末尾的值吗?还是我完全理解错误了?


2
编译器并不知道NAME_OF_FILE是特殊的,它只是按照约定而已。它是文件的“锁”(即)文件可以被多次#include,但锁防止编译器多次读取锁结构和相应的#endif之间的内容。实际上是C预处理器完成这个过程。如果您逐步跟随逻辑,第一次#ifndef为真,因此包括[1st] #define和其余部分。在第二次尝试中,#ifndef为假,并跳转到底部的#endif - Craig Estey
4个回答

4

这两个定义没有本质区别。 #define NAME_OF_FILE#define NUM_CONST 5 都是同一种东西。它们定义了令牌的纯文本替换(在第一个示例中,替换内容为空)。

例如,您可以放置以下代码:

printf("%d\n", NAME_OF_FILE NUM_CONST NAME_OF_FILE);

在上述替换后,代码将变为:

printf("%d\n", 5);

这是正确的。没有“魔法”。执行这些替换的编译步骤通常称为“预处理”。

NAME_OF_FILE并不是指.h文件本身,而是使用ifndef指令实现了不重复编译相同代码的目标。


4
它并没有特定的含义。 NAME_OF_FILE 可以是任何东西。你可以有:
#ifndef PRETTY_PINK_PRINCESS
#define PRETTY_PINK_PRINCESS
/* definitions */
#endif

同样的效果可以实现。使用文件名只是一种约定,因为这样做可以使其更具唯一性。


3

#define IDENTIFIER 定义了标识符,以便于在使用 #ifdef 时进行判断,但是它被定义成了一个空字符串。

因此,

#define NAME_OF_FILE

int main()
{
    int x = NAME_OF_FILE;
}

会解析为。
int main()
{
    int x = ;
}

因此,这里不存在“知道”的问题,只有一个被定义但为空的情况。 (这就是一些样式指南建议使用#define NAME_OF_FILE NAME_OF_FILE的原因,因此如果NAME_OF_FILE恰好在源代码中使用,则会被预处理器替换为自己。)

关于 #define NAME_OF_FILE NAME_OF_FILE 的好主意!我从未听说过这个,你有任何提到它的链接吗? - anatolyg
@anatolyg:自从我开始使用Astyle等工具来处理纯样式问题后,已经有很长一段时间了(大约15年)。重要的事情变得自然而然,而仅仅是样式上的问题可以通过Astyle等工具来解决。我发现这个工具很实用,所以就一直在用。至于我从哪里得到它的,我也不记得了。 - DevSolar

0

对于编译器来说,这两个语句都是宏类型。

#define NAME_OF_FILE

#define NUM_CONST 5

这个结构

#ifndef NAME_OF_FILE
#define NAME_OF_FILE
.
. //my header file content
.
#endif

正在进行的操作是,首次处理标头时,宏"NAME_OF_FILE"未定义,因此它被定义并且整个标头文件内容被处理。第二次编译器再次处理此内容,因为标头已经在项目中包含了多次,所以宏现在已经被定义,标头文件不会再次被处理。 同样,"c-code"不知道例如宏__TEST_H是由于标头文件名为'test.h'而存在的。您所指的可能是,您的IDE自动生成了宏,然后创建了标头文件,并且IDE为用户方便起见调用了该宏。就像另一个人已经说过的那样,您可以重命名宏(我指的是在整个项目中重命名它),代码将编译并且通常会像以前一样运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接