格式:
#ifndef _TEST_H // ifndef( if not define)
#define _TEST_H //一般是文件名的大写
/*
中间有许多定义啦声明啦!;;
*/
#endif
简单理解
#ifndef _TEST_H 意思是: _TEST_H 如果没有定义,那么为真。
进行下一句#define _TEST_H,意思是: 对 _TEST_H 进行定义,然后执行后面的语句
直到#endif 结束
如果我们多个文件都 #include“test.h”,
在编译阶段(ifndef是在编译阶段起作用滴!)
这多个文件如果一个先编译了,那么_TEST_H就被定义了。
当编译到第二个文件的时候,那么在开始的判断(#ifndef _TEST_H)就会判断为假
#ifndef _TEST_H和
#endif之间的代码也就不会再次被包含
程序会自动跳出test.h这个文件的重复编译。
这样就避免了重复编译文件。
目的:
在头文件中加入#ifndef或#ifdef等宏定义,是为了防止重复定义。
主要防止头文件里的全局变量重复定义,建议不要在头文件里定义变量。
重复声明可以,但是重复定义是不可以的。
重复声明只要名称完全相同即可。但是重复定义会出现编译错误的,即使同名也不可以
我们知道,头文件一般是用来声明的,会被其他的源文件和头文件include,当被多个文件include的时候就会造成重复声明。 为了使得只声明一次,引入前面所说的宏定义,一般以文件名大写和_来当宏的名字。
这个宏是给预处理器用的,通常预处理变量用大写,所以这些宏定义都用大写。为了方便,一般将大写的文件名作为预处理器变量,其实在#ifndef后面加什么都都可以,用文件名只是为了好区分。它只是用来定义一个预处理器变量。
“头文件被重复引用”示例:
// b.cpp #include "a.h" // 执行,包含c.h,导致定义C_H #include "c.h" // 执行,包含c.h,因为上一行已经定义了C_H,所以条件为假,#define一下的代码没有执行
// a.h #ifndef A_H #define A_H #include "c.h" #endif
// c.h #ifndef C_H #define C_H //pass #endif
注:
__XXX_H也是宏 即 _TEST_H是宏,宏是一种预处理指令,宏是用“#define"语句定义的
习惯上把这个宏定义成跟头文件名相似或一样。
就是头文件是test.h 对应的宏就是 _TEST_H
实际上头文件是test.h 我们也可以定义宏为 XXX,就是一个名字而已
只不过采用test.h对应 _TEST_H使程序更好理解而已
另外不同的.h文件的宏名称要保证不同,类似人的身份证
使用宏有以下几点好处:
(1)在输入源代码时,可省去许多键入操作。
(2)因为宏只需定义一次,但可以多次使用,所以使用宏能增强程序的易读性和可靠性。
(3)使用宏不需要额外的开销,因为宏所代表的代码只在宏出现的地方展开,因此不会引起程序中的跳转。
(4)宏的参数对类型不敏感,因此你不必考虑将何种数据类型传递给宏。