C&C++ 头文件作用

参考:http://www.cnblogs.com/polestar/archive/2012/02/24/2366724.html +http://blog.csdn.net/yeyuangen/article/details/6800672 + http://xinklabi.iteye.com/blog/655564

============c头文件============

------------由来------------

     那是一个被遗忘的年代,在编译器只认识.c(.cpp))文件,而不知道.h是何物的年代。那时的人们写了很多的.c(.cpp)文件,渐渐地,人们发现在很多.c(.cpp)文件中的声明语句就是相同的,但他们却不得不一个字一个字地重复地将这些内容敲入每个.c(.cpp)文件。但更为恐怖的是,当其中一个声明有变更时,就需要检查所有的.c(.cpp)文件,并修改其中的声明,啊~简直是世界末日降临!

      终于,有人(或许是一些人)再不能忍受这样的折磨,他(们)将重复的部分提取出来,放在一个新文件里,然后在需要的.c(.cpp)文件中敲入#include XXXX这样的语句。这样即使某个声明发生了变更,也再不需要到处寻找与修改了---世界还是那么美好!
      因为这个新文件,经常被放在.c(.cpp)文件的头部,所以就给它起名叫做“头文件”,扩展名是.h. 从此,编译器(其实是预处理器)就知道世上除了.c(.cpp)文件,还有个.h的文件,以及一个叫做#include命令。

------------实质-----------

     从C编译器角度看(参考文章编译过程),.h和.c没啥必然联系,就是改名为.txt、.doc也没有大的分别。因为 #include "xx.h" 这个宏其实际意思就是把当前这一行删掉,把 xx.h 中的内容原封不动的插入在当前行的位置。理论上来说头文件里与C文件的内容,只要是C语言所支持的,无论写什么都可以的,比如你在头文件中写函数体,只要在任何一个C文件包含此头文件就可以将这个函数编译成目标文件的一部分。

------------头文件应该有什么-----------

--1.如果在头文件中实现一个函数体,那么如果在多个C文件中引用它,而且又同时编译多个C文件,将其生成的目标文件连接成一个可执行文件,在每个引用此头文件的C文件所生成的目标文件中,都有一份这个函数的代码,如果这段函数又没有定义成局部函数,那么在连接时,就会发现多个相同的函数,就会报错;
--2.如果在头文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此头文件的C文件中同样存在相同变量名的拷贝,关键是此变量被赋了初值,所以编译器就会将此变量放入DATA段,最终在连接阶段,会在DATA段中存在多个相同的变量,它无法将这些变量统一成一个变量,也就是仅为此变量分配一个空间,而不是多份空间,假定这个变量在头文件没有赋初值,编译器就会将之放入BSS段,连接器会对BSS段的多个同名变量仅分配一个存储空间;
--3.如果在C文件中声明宏,结构体,函数等,那么我要在另一个C文件中引用相应的宏,结构体,就必须再做一次重复的工作,如果我改了一个C文件中的一个声明,那么又忘了改其它C文件中的声明,这不就出了大问题了,程序的逻辑就变成了你不可想象的了,如果把这些公共的东东放在一个头文件中,想用它的C文件就只需要引用一个就OK了!这样岂不方便,要改某个声明的时候,只需要动一下头文件就行了
--4.当你需要将你的代码封装成一个库,让别人来用你的代码,你又不想公布源码,那么人家如何利用你的库呢?也就是如何利用你的库中的各个函数呢??一种方法是公布源码,别人想怎么用就怎么用,另一种是提供头文件,别人从头文件中看你的函数原型,这样人家才知道如何调用你写的函数,就如同你调用printf函数一样。

总结:

--h文件里应该有什么:常量,结构,类型定义,函数,变量声明。{区别(数据)类型定义 和 数据/变量定义}
--h文件不应该有什么:变量定义, 函数定义。

------------头文件作用-----------

--1.方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明;
--2. 使函数的作用域从函数声明的位置开始,而不是函数定义的位置(实践总结);
--3 .提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h);

备注:include包含问题:虽然申明和类型定义可以重复,推荐使用条件编译;

============c++头文件============

--类似c头文件作用,不过头文件中多了类的结构声明。

备注:

--1.头文件中只存放“声明”而不存放“定义”,在C++ 语法中,类的成员函数可以在声明的同时被定义,并且自动成为内联函数。这虽然会带来书写上的方便,但却造成了风格不一致,弊大于利。建议将成员函数的定义与声明分开,不论该函数体有多么小。

--2.相似原因:C++ 中要使用头文件,最主要的原因是 C++ 的同一个项目可能有多个源代码文件,要命的是这些源代码是分别单独编译的。也就是说,在编译其中一个文件时,编译器并不知道其它文件中定义的内容,如类、全局变量等。这就要求我们必须在要使用某个类、函数或变量的每个文件中声明它,否则 C++ 是无法找到它的。很多文件可能都需要使用加法。假设有一个文件 b.cpp 需要使用这个函数,那么,它必须先声明它,虽然不需要再重写。如果有很多文件都要使用这个函数,那么这会变得麻烦,特别的,如果你写了一个类,那么你需要维护大量的声明(对于每一个 public 对象),并且如果你的类的定义发生了改变,你可能不得不改变无数个声明。



你可能感兴趣的:(C&C++ 头文件作用)