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 */
编译器第一次包含 .h
,MY_aWeSoMe_VARIABLE
尚未定义,因此预处理器将进入 if
,定义变量,包含所有.h
的代码。如果您的编译器第二次或多次包含 .h
,则该变量已经定义,因此预处理器不会进入 if
。由于 .h
的所有内容都在 if
中,因此它不会执行任何操作。
由于命名变量 MY_aWeSoMe_VARIABLE
非常愚蠢,人们倾向于将其命名为 MY_FILE_NAME
或 MY_FILE_NAME_H
,但这不是强制性的,实践实际上因开发者而异另一个。
只是一个初学者的问题,#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 */
编译器第一次包含 .h
,MY_aWeSoMe_VARIABLE
尚未定义,因此预处理器将进入 if
,定义变量,包含所有.h
的代码。如果您的编译器第二次或多次包含 .h
,则该变量已经定义,因此预处理器不会进入 if
。由于 .h
的所有内容都在 if
中,因此它不会执行任何操作。
由于命名变量 MY_aWeSoMe_VARIABLE
非常愚蠢,人们倾向于将其命名为 MY_FILE_NAME
或 MY_FILE_NAME_H
,但这不是强制性的,实践实际上因开发者而异另一个。