#ifndef/#define/#endif的作用
在C语言中,一个文件可以包含多个头文件,而头文件之间又是可以相互引用的,这将导致一个文件可能间接多次包含某个头文件,从而导致某些头文件被重复引用多次。
例如,有3个文件a.h,b.h
和c.h
,其中b文件包含了a.h,而c文件中又分别包含了a.h和b.h两个文件。于是问题出来了,由于嵌套包含文件的原因,头文件a.h被两次包含在源文件c中。在这里,如果头文件中没有防止多次编译的语句,有可能会引起以下两种后果。
- 某些头文件重复引用只是增加了编译器编译的工作量,导致编译效率降低,不会引起太大的问题。但是,对于较大的工程而言,编译效率低下是一件痛苦的事情。
- 某些头文件重复引用,有可能会引起意想不到的严重错误。比如,在头文件中定义了全局变量,将会导致全局变量被重复定义。
避免同一个头文件被多次包含,重复引用,最常用的方法就是利用#ifndef/#define/#endif
结构产生预处理块来方式头文件被重复引用:
#ifndef __HEADERNAME_H__
#define __HEADERNAME_H__
//声明,定义语句
#endif
在上面的预处理块中,当第一次引用(include)头文件时,由于__HEADERNAME_H__
还没有被宏定义过,既满足#ifndef __HEADERNAME_H__
,从而执行#define __HEADERNAME_H__
以及其他内容。
如果因为编码者的不小心或者嵌套包含等原因造成了这个头文件被多次引用(include),那么#ifndef __HEADERNAME_H__
判断条件将在第二次引用(include)头文件时得不到满足,因此不执行后面的内容,直接跳到#endif
#pragma once
在头文件的最开始加入这条指令表示:这个头文件只被编译一次,是由编译器提供保证,同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
#pragma once
与#ifdef,#ifndef,#endif
的区别
#ifndef,#define,#endif
是C/C++语言中的宏定义,通过宏定义来避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,移植性好,所以如果写的程序要跨平台,最好使用这种方式。但是缺点是宏名字不能冲突。#pragma
可以避免名字冲突,缺点就是如果某个头文件有多份拷贝,本方法不能保证它们不被重复包含。且不是所有编译器都支持这种方式。
参考 https://blog.csdn.net/qq_34342154/article/details/78888174