在C中,#定义了什么而没有赋值?[副本]

kyxcudwk  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(74)

此问题在此处已有答案

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

ibps3vxo

ibps3vxo1#

define预处理指令的格式为# defineidentifierpreprocessing-tokens,以换行符结尾。preprocessing-tokens是零个或多个预处理标记的列表。它可以是空的,也就是说,它可以具有零个令牌。这意味着,当在宏替换发生的地方遇到identifier时,它将被替换为空。 `#if`或`#elif`指令中的`#ifdef `identifier#ifndefidentifier或`defined `identifier形式的测试测试是否定义了identifier。如果它没有被定义(或者它的定义被#undef指令删除),那么测试表明它没有被定义。如果它被定义了,那么测试指示它被定义了,即使该定义是针对零个令牌的。
带有零个标记的定义与没有定义是不同的,definedidentifier``将为前者的true和后者的false。

脚注

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

8cdiaqws

8cdiaqws2#

这是一个语言习惯用法(我会注解它):

#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

bz4sfanl

bz4sfanl3#

它实际上定义了“除了它自己之外没有别的”。也就是说:你可以定义一个宏而不给它指定一个特定的值。由于可以检查给定宏是否已定义,因此可以询问给定宏的简单“存在”。
这对于指示上下文(例如,如果您正在为给定的OS进行编译)和/或某些资源的可用性非常有用。
在该特定示例中,这被称为“防护”:如果之前没有这样做,它将定义自己,并包括文件的其余部分,这些部分完全嵌入在#ifdef … #endif子句中。
这是用来实现一种require_once的,如果需要的话,它会被包含,但不会被多次包含。例如,在全局范围内定义函数或声明变量时,这是必需的。

相关问题