添加这 3 个标头的正确语法是:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
是一个预#ifndef
处理器指令,后面跟着一个标记,让它成为X
。它将检查是否X
已通过#define
预处理器指令定义,如果没有,则后续行将由您的编译器处理,直到对应的#endif
. 例如;
// #define X
// #define X 123456
#ifndef X
/* some code */
#endif
上面的内容可以理解为X 未定义。/* some code */
仅当X
未定义时才考虑该部分,在这种情况下,未定义X
,所以它会。如果我取消注释上述任何一个,编译器将忽略#define ...
该部分。/* some code */
包含保护是利用我上面解释过的这个东西的东西#ifndef
。您不必担心这些,直到您为自己制作头文件。
头文件通常(通常)在自己内部有#include guard
s。无论他们做什么,他们首先检查是否已经定义了某个特定的令牌。如果没有,那么他们将自己定义该令牌并做任何事情。如果它已经被定义,那么他们什么也不做。这是为了防止对内部任何内容进行不必要的多重定义。例如,如果您要检查<stdio.h>
MSVC 2013,您会看到它的开头和结尾如下:
#ifndef _INC_STDIO
#define _INC_STDIO
// hundreds of lines in between
#endif
多亏了这一点,如果您要编写如下内容:
#include <stdio.h>
#include <stdio.h>
// ...
在您的代码中,第二个#include
几乎什么都不做,因为第一个已经执行了 line #define _INC_STDIO
,它定义_INC_STDIO
并阻止了几乎所有内容在<stdio.h>
后续包含中再次执行。
这并不是为了防止对不起,程序员的“愚蠢”错误,当一个头文件包含另一个头文件本身时,它很有用。例如,在 MSVC 2013 中,两者都<stdio.h>
尝试<stdlib.h>
将其包含<crtdefs.h>
为他们的第一个操作。现在,如果<crtdefs.h>
包含两次,里面的一堆类型定义将被多次定义,而它们不应该。当然,我可以在我的代码之上写下以下内容:
#include <stdio.h>
#include <stdlib.h>
// ...
#include
守卫会为我节省一天的时间,防止内容被<crtdefs.h>
多次执行。