欢迎来到天天文库
浏览记录
ID:50414833
大小:34.34 KB
页数:5页
时间:2020-03-08
《头文件的部分规则:重定义相关.docx》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、如何在C语言中自己写头文件一些初学C语言的人,不知道头文件(*.h文件)原来还可以自己写的。只知道调用系统库函数时,要使用#include语句将某些头文件包含进去。其实,头文件跟.C文件一样,是可以自己写的。头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h保存就行了。头文件中一般放一些重复使用的代码,例如函数声明,变量声明,常数定义,宏的定义等等。当使用#include语句将头文件引用时,相当于将头文件中所有内容,复制到#include处。为了避免因为重复引用而导致的编译错误,头文件常具有#ifndef LAB
2、EL#define LABEL //代码部分#endif的格式。其中,LABEL为一个唯一的标号,命名规则跟变量的命名规则一样。常根据它所在的头文件名来命名,例如,如果头文件的文件名叫做hardware.h,那么可以这样使用:#ifndef __HARDWARE_H__#define __HARDWARE_H__ //代码部分#endif这样写的意思就是,如果没有定义__HARDWARE_H__,则定义__HARDWARE_H__,并编译下面的代码部分,直到遇到#endif。这样,当重复引用时,由于__HARDWARE_H
3、__已经被定义,则下面的代码部分就不会被编译了,这样就避免了重复定义。另外一个地方就是使用include时,使用引号与尖括号的意思是不一样的。使用引号(“”)时,首先搜索工程文件所在目录,然后再搜索编译器头文件所在目录。而使用尖括号(<>)时,刚好是相反的搜索顺序。假设我们有两个文件名一样的头文件hardware.h,但内容却是不一样的。一个保存在编译器指定的头文件目录下,我们把它叫做文件I;另一个则保存在当前工程的目录下,我们把它叫做文件II。如果我们使用的是#include,则我们引用到的是文件I。如果
4、我们使用的是#include“hardware.h”,则我们引用的将是文件II。笔者以前就遇到过一个同事问,为什么他修改了那个头文件里面的内容,好象跟没有修改一样?就是因为他有两个一样的头文件(就像我们刚描述的那样),他是使用#include引用的,而他修改时,却是当前工程所在的目录下的那个文件。一.RULE1:每个头文件都用以下宏包起来,防止被其他文件多次包含。 #ifndef__FILENAME_H__ #define__FILENAME_H__ (……文件内容……) #endi
5、f//__FILENAME_H__RULE2:在定义一个宏的时候,考虑是否需要检测是否已经被定义过。 #ifndefMACRO_NAME #defineMACRO_NAME MACRO_VALUE #endifRULE3:头文件中不要去定义全局变量,也就是说头文件中的所有语句不能涉及实际内存的分配。对于RULE1,基本上大家都会这么做,当然也可以用pragmaonce来代替,只是pragmaonce的通用性不好,所以大家大多选择比较麻烦一点的RULE1中的做法。RULE1不是我想说的重点。RULE2主要是为
6、了防止宏重定义。在同一个工程中,尤其是一较大的工程中,同一个名字的宏在多个文件被定义是很正常的,比如BREW中RELEASEIF往往在多处被定义。在VC的编译器中,即使重定义也不会报错,甚至连Warning都没有,但是TCC会作为Error来处理。举例:a.h中定义了宏A,b.h中也定义了宏A,他们都没有用ifndef包起来。然后某个源文件同时包含了这两个文件。对于严格的编译器来说,会出现重定义的错误,而对于检查较松的编译器,后者的定义会覆盖前者的定义(有的时候不同地方对同一个宏的定义不同)。有的时候,某些头文件我们需要包含进来,
7、但是我们不关心那些头文件有没有已经定义了自己想要定义的宏或者自己想要定义的宏名被那些头文件定义成了什么样子,我们可以先undef掉那个宏,然后再定义自己的宏,这样可以保证自己用的宏是自己想要的定义。用RULE2的做法确实存在这样一个问题,我们不能确定自己用的宏是什么样子的(和包含的头文件以及它们的顺序有关系,这意味着本来都正常的代码,忽然有一天你又把另外一个头文件包含进来,结果这个宏的定义可能就不再是原来的那个了)。如果需要确认,可以让编译器生成预处理后的文件查看,不过一般情况下不需要这么做。今天有个同事碰到了这样一个问题,让我过
8、去帮他看看:我看到的错误是说某个头文件的某个宏重定义了。据他描述是因为他在某个C源文件里包含了多个头文件导致的。可是这些被他包含进来的头文件中却没有那个提示出错的头文件,另外这个重定义的宏对他来说一点用也没有。当时我怎么也没想不明白,既然没有包含进
此文档下载收益归作者所有