#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_H
将 HEADERFILE_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
)、常量(如 3
、4u
或 1.8e4
)、C 运算符之一或特殊字符(如*
或 +=
),或 C 语言的某些其他组件。
这是一个语言成语(我会评论它):
#ifndef HEADERFILE_H
在此和最后一个 #endif
之间的所有内容都包含在编译中,但前提是 HEADERFILE_H
之前未定义。
#define HEADERFILE_H
我们在块中做的第一件事就是#define
标识符,所以下次我们再次找到这个片段时,#ifndef
和#endif
之间的内容就不会了#include
d 再次(因为标识符声明)。
// some declarations in
// the header file.
这个块只会被包含一次,即使你 #include
这个文件多次。
#endif
这标志着受保护块的结束。
通常会包含一些文件,实际上 #include
是另一个文件,而该文件又包含另一个文件,导致您不知道哪些文件已被包含,哪些文件未被包含吨。这种措辞允许你受到保护,并且能够 #include
同一个文件多次(通常你不能,因为一些定义不能在同一个编译单元中重复,例如声明)上面的行将包含内容并定义标识符,使下一个包含(有效完成)不包含内容,因为标识符在第二次和以后的时间中显示为 #definen
。
我经常看到这样的代码
#ifndef HEADERFILE_H
#define HEADERFILE_H
// some declarations in
// the header file.
#endif
我想知道 #define HEADERFILE_H
将 HEADERFILE_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
)、常量(如 3
、4u
或 1.8e4
)、C 运算符之一或特殊字符(如*
或 +=
),或 C 语言的某些其他组件。
这是一个语言成语(我会评论它):
#ifndef HEADERFILE_H
在此和最后一个 #endif
之间的所有内容都包含在编译中,但前提是 HEADERFILE_H
之前未定义。
#define HEADERFILE_H
我们在块中做的第一件事就是#define
标识符,所以下次我们再次找到这个片段时,#ifndef
和#endif
之间的内容就不会了#include
d 再次(因为标识符声明)。
// some declarations in
// the header file.
这个块只会被包含一次,即使你 #include
这个文件多次。
#endif
这标志着受保护块的结束。
通常会包含一些文件,实际上 #include
是另一个文件,而该文件又包含另一个文件,导致您不知道哪些文件已被包含,哪些文件未被包含吨。这种措辞允许你受到保护,并且能够 #include
同一个文件多次(通常你不能,因为一些定义不能在同一个编译单元中重复,例如声明)上面的行将包含内容并定义标识符,使下一个包含(有效完成)不包含内容,因为标识符在第二次和以后的时间中显示为 #definen
。