779-如何防止C语言头文件被重复包含

如何防止C语言头文件被重复包含?

一般情况下,我们都是把函数声明、类定义、模板定义等写到一个头文件里,需要时将相应的头文件用#include包含到源文件(*.c文件)里来。但头文件中又允许包含其它的头文件,这样就难免发生某个头文件被重复地包含。
我们可以使用编译预处理命令避免这种情况的发生。

方法1:使用#ifndef

例如,你想确保头文件max.h不会被重复包含,则你可以采取如下的形式:
在这里插入图片描述
第一条预处理命令的意思:如果MAXMIN_H不为真,说明此文件没被包含过,此命令后面的源代码有效(相当于:‘如果大门没关,请您进来’);

第二条预处理命令的意思:把MAXMIN_H置为真(相当于:请您把门锁插上,不让第二个人进来)。

最后一条预处理命令的意思:是为了标出接受上述处理的源程序的范围(相当于您已经走到了后门)。

假定有以下几个头文件及其包含关系为:
file1.h,file2.h,file3.h,file4.h,file5.h,main.c
那么:file3.h包含file1.h,file2.h,file4.h包含file1.h,file2.h,file5.h包含file3.h,file4.h
就会导致在file5中对file1和file2的反复包含,编译时就会报错

解决方法1:
#define
endif
即每个文件在定义时都写成以下情势(以file1.h为例):

#ifndef H_FILE1
#define H_FILE1
#include<stdio.h>
#include<math.h>

........

#endif

file3.h:

#ifndef H_FILE3
#define H_FILE3
#include<stdio.h>
#include<math.h>
#inlcude”file1.h”
#include”file2.h”

..........

#endif

方法2:在每个文件的头部定义:#pragma once

在每个文件的头部定义:#pragma once(用于解释本文件中的内容只应用一次)
例:fiel1.h:

#pragma once
#include<stdio.h>
#include<math.h>

................

file3.h:

#pragma once
#include<stdio.h>
#include<math.h>
#include”file1.h”

................

#pragma once和 #ifndef的区别

这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次。

#pragma once用来防止某个头文件被多次include,
#pragma once是编译相关,就是说这个编译系统上能用,但在其他编译系统不一定可以,也就是说移植性差,不过现在基本上已经是每个编译器都有这个定义了。

#ifndef,#define,#endif用来防止某个宏被多次定义。
#ifndef,#define,#endif这个是C语言相关,这是C语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C语言的编译器上都是有效的,如果写的程序要跨平台,最好使用这种方式

#ifndef方式 和 #pragma once方式

在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。

方式1:

#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__

... ... //一些声明语句

#endif

方式2:

#pragma once

... ... //一些声明语句

1、#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况

2、#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。

3、方式1 由语言支持所以移植性好,方式2 可以避免名字冲突
#pragma once方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受语言天生的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,换言之,它的兼容性不够好。也许,再过几年等旧的编译器死绝了,这就不是什么问题了。

  • 14
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值