Header 文件和宏有什么关系?

How Header files and macros are related?

只是一个初学者的问题,#ifndef SOME_HEADER_H 是怎么回事可以理解,它是条件编译的预处理器指令,如果已经包含了一些 header(我可能错了,请纠正我?)移动上,如果不是,include 它,我在一些博客上读到用这些词代替的字母句子,如果它被定义继续 #define 它,我想我们可以只包括一个 header 文件没有定义 header 文件,如何定义 header 文件,这里有什么关系?第二个问题,文件名是 foo.h ,当他试图检查它是否被定义时,他做了 #ifndef FOO_H #define FOO_H,好的 foo.h 是如何被翻译成 FOO_H 的, c 机制知道他在谈论那个特定文件还是他做了什么 before-word?谢谢你的时间!

你这里有一个 header 守卫:

文件:some_header.h

#ifndef SOME_HEADER_H  // if SOME_HEADER_H is not defined, enter the
                       // #ifndef ... #endif block
#define SOME_HEADER_H  // and define SOME_HEADER_H

struct foo {
    int x;
};

#endif

这可以防止 header 被多次包含在同一个翻译单元中,从而避免多次定义相同的实体。宏 SOME_HEADER_H 将保持定义,直到翻译单元完成,所以无论这个 header 被包含在翻译单元中多少次(通过其他 header 文件隐含地)它的内容只会是为该翻译单元解析一次。

您现在可以这样做:

文件:some_other_header.h

#ifndef SOME_OTHER_HEADER_H
#define SOME_OTHER_HEADER_H

#include "some_header.h" // this header uses some_header.h

struct bar {
    struct foo x;
};

#endif

一个程序现在可以同时包含 header 个文件而不会出现 redefinition of 'foo'.

这样的错误

文件:main.cpp

#include "some_header.h"
#include "some_other_header.h"

int main() {}

一个 non-standard 但非常流行的替代上面显示的经典 header 守卫的是 #pragma once 它做同样的事情(如果你的预处理器支持它):

文件:some_header.h

#pragma once
// no need for a named macro or #endif

struct foo { ... };

没有将foo.h翻译成FOO_H这样的事情,也没有“定义.h已经包含”这样的事情。使用预处理器变量只是 C 开发人员确保 .h 不被包含两次的标准方法。

在 C 预处理器中,您可以使用诸如 #if#else#endif 之类的东西来进行逻辑处理。您还可以 #define 变量,来存储信息。您还可以使用函数 defined(...) 检查是否已定义 C 预处理器变量。 #ifdef MY_VARIABLE 指令只是 #if defined(MY_VARIABLE) 的 shorthand,而 #ifndef 正好相反。

另一方面,您不希望 .h 被包含两次,有几种方法可以做到这一点,但标准方法是:

/* Check if my variable has already been declared */
#ifndef MY_aWeSoMe_VARIBLE

/* If we are in here, it mean that it is not */
/* So let's declare it */
#define MY_aWeSoMe_VARIBLE

/* You can write some more code here, like your .h stuff */

/* And of course, it's time to close the if */
#endif  /* This closes the MY_aWeSoMe_VARIABLE ifndef */

编译器第一次包含 .hMY_aWeSoMe_VARIABLE 尚未定义,因此预处理器将进入 if,定义变量,包含所有.h 的代码。如果您的编译器第二次或多次包含 .h,则该变量已经定义,因此预处理器不会进入 if。由于 .h 的所有内容都在 if 中,因此它不会执行任何操作。

由于命名变量 MY_aWeSoMe_VARIABLE 非常愚蠢,人们倾向于将其命名为 MY_FILE_NAMEMY_FILE_NAME_H,但这不是强制性的,实践实际上因开发者而异另一个。