#define without assignment 在 C 中赋值给什么?

What does #define without assignment assign to in C?

我经常看到这样的代码

#ifndef HEADERFILE_H
#define HEADERFILE_H
// some declarations in
// the header file.
#endif

我想知道 #define HEADERFILE_HHEADERFILE_H 定义为什么?

我试过

cout<<HEADERFILE_H<<endl;

但我得到了

error: expected expression

它实际上定义了“除了它自己之外别无他物”。也就是说:您可以定义一个宏而不为其分配特定值。由于您可以检查给定的宏是否已定义,因此您可以询问给定宏的简单“存在”。

这对于指示上下文很有用(例如,如果您正在针对给定的 OS 进行编译)and/or 某些资源的可用性。

在此特定示例中,这称为“守卫”:如果之前未首先完成此操作,它将自行定义,并包括文件的其余部分,该文件完全嵌入 #ifdef … #endif 子句。

这用于实现一种 require_once,即在需要时将包含的内容,但不会多次包含。例如,当您在全局范围内定义函数或声明变量时,这是必需的。

A define 预处理指令的形式为 # define <i>identifier</i> <i>preprocessing-tokens</i>, 以换行符结尾。 <i>preprocessing-tokens</i> 是零个或多个预处理标记的列表。它可能是空的,也就是说,它可能有零个标记。也就是说,当<i>identifier</i>出现在宏替换的地方,就什么都不替换了。1

测试形式 #ifdef <i>identifier</i>, #ifndef <i>identifier</i>define <i>identifier</i>#if#elif 指令中测试是否 <i>标识符</i>是否定义。如果它没有被定义(或者它的定义被 #undef 指令删除),那么测试表明它没有被定义。如果它已被定义,则测试表明它已被定义,即使该定义是针对零标记的。

零标记的定义与根本没有定义不同,定义的<i>标识符</i>将对前者评估为真,对假对于后者。

脚注

1 如果列表确实有标记,那么 <i>identifier</i> 将被替换为那些令牌和其中的 ### 运算符将被应用。预处理标记主要是标识符(如 foo34)、常量(如 34u1.8e4)、C 运算符之一或特殊字符(如*+=),或 C 语言的某些其他组件。

这是一个语言成语(我会评论它):

#ifndef HEADERFILE_H

在此和最后一个 #endif 之间的所有内容都包含在编译中,但前提是 HEADERFILE_H 之前未定义。

#define HEADERFILE_H

我们在块中做的第一件事就是#define标识符,所以下次我们再次找到这个片段时,#ifndef#endif之间的内容就不会了#included 再次(因为标识符声明)。

// some declarations in
// the header file.

这个块只会被包含一次,即使你 #include 这个文件多次。

#endif

这标志着受保护块的结束。

通常会包含一些文件,实际上 #include 是另一个文件,而该文件又包含另一个文件,导致您不知道哪些文件已被包含,哪些文件未被包含吨。这种措辞允许你受到保护,并且能够 #include 同一个文件多次(通常你不能,因为一些定义不能在同一个编译单元中重复,例如声明)上面的行将包含内容并定义标识符,使下一个包含(有效完成)不包含内容,因为标识符在第二次和以后的时间中显示为 #definen