此问题在此处已有答案:
whats happens when using #define with no replacement string?(2个答案)
20天前关闭。
我经常看到这样的代码
#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
型
3条答案
按热度按时间ibps3vxo1#
define
预处理指令的格式为# define
identifierpreprocessing-tokens
,以换行符结尾。
preprocessing-tokens是零个或多个预处理标记的列表。它可以是空的,也就是说,它可以具有零个令牌。这意味着,当在宏替换发生的地方遇到
identifier时,它将被替换为空。 `#if`或`#elif`指令中的`#ifdef `identifier
、#ifndef
identifier或`defined `identifier
形式的测试测试是否定义了identifier
。如果它没有被定义(或者它的定义被#undef
指令删除),那么测试表明它没有被定义。如果它被定义了,那么测试指示它被定义了,即使该定义是针对零个令牌的。带有零个标记的定义与没有定义是不同的,
defined
identifier``将为前者的true和后者的false。脚注
1如果列表中确实有令牌,那么
identifier
将被替换为这些令牌,并且其中的#
和##
运算符将被应用。预处理标记主要是一个标识符(如foo34
),一个常量(如3
,4u
或1.8e4
),一个C操作符或特殊字符(如*
或+=
),或C语言的某些其他组件。8cdiaqws2#
这是一个语言习惯用法(我会注解它):
字符串
在此和最后一个
#endif
之间的所有内容都包含在编译中,但前提是之前没有定义HEADERFILE_H
。型
我们在块中做的第一件事是
#define
标识符,所以下次我们再次找到这个片段时,#ifndef
和#endif
之间的内容将不再是#include
d(因为标识符声明)。型
这个块将只包含一次,即使你
#include
这个文件多次。型
并且这标志着受保护块的结束。
包含一些文件是很常见的,实际上,
#include
是另一个文件,而这个文件又包含另一个文件,这导致您不知道哪些文件被包含了,哪些没有。这种措辞允许您受到保护,并且能够多次#include
相同的文件(通常您不能,因为某些定义不能在同一编译单元中重复,例如。声明),上面的行将包括内容并定义标识符,使得下一个包含(有效完成)不包括内容,因为标识符在第二次和以后的时间中显示为#definen
。bz4sfanl3#
它实际上定义了“除了它自己之外没有别的”。也就是说:你可以定义一个宏而不给它指定一个特定的值。由于可以检查给定宏是否已定义,因此可以询问给定宏的简单“存在”。
这对于指示上下文(例如,如果您正在为给定的OS进行编译)和/或某些资源的可用性非常有用。
在该特定示例中,这被称为“防护”:如果之前没有这样做,它将定义自己,并包括文件的其余部分,这些部分完全嵌入在
#ifdef … #endif
子句中。这是用来实现一种
require_once
的,如果需要的话,它会被包含,但不会被多次包含。例如,在全局范围内定义函数或声明变量时,这是必需的。