现在的位置: 首页 > 综合 > 正文

C语言中源文件和头文件的那些事

2018年03月18日 ⁄ 综合 ⁄ 共 1730字 ⁄ 字号 评论关闭

博主新开了个人站点,你也可以在这看到这篇文章,点击打开链接


之前学习C语言浮皮潦草,基础不扎实,有很多比较基础的东西都不曾有信息去仔细了解。而之前也从来没有过多的去思考过关于一些基础性、原理性的东西。做的项目更是基于从网上down的修改物品。现在我表示愧疚,表示对过往青春的不负责任的行为进行谴责。虽然现在我也不能确切的讲将来一定会一直沿着技术的道路走下去,但是近一年来的经历和周围环境使我越发感觉到了做一名简单快乐的技术人员也是一份十分惬意的事情,关于这方面以后再慢慢讲吧。说的有点偏离主题了,下面还是说正事吧。本文主要讨论一些在一个C语言环境中cpp源文件与header文件之间的关系,讨论了为什么我要使用头文件这个东西。

首先,在一个C语言的工程中,我们可以将所有东西都放在一个.cpp文件内.
然后编译器就将这个.cpp编译成.obj,obj是什么东西? 就是编译单元了.一个程序,可以由一个编译单元组成, 也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话, 就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上 就可以分别放在一个单元,也就是cpp里面) 那么就是一个.cpp对应一个.obj,然后将所有的obj链接起来(通过一个叫链接器的程序), 组成一个.exe,也就是程序了.

 如果一个.cpp要用到另一个.cpp定义的函数怎么办?
只需在这个.cpp种写上他的函数声明 就可以了.其余工作由链接器帮你完成,你可以随便调用该函数. 链接器将所有的obj连接起来,但是如果碰巧有相同的函数或外部变量怎么办?他如何识别? 一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名. 但是只得庆幸的是,c++可以通过一种叫做链接属性的关键字来限定,你这个函数是属于整个程序 公用的,还是只是在一个编译单元obj里面使用的. 这些关键字就是extern 和 static; extern是外部链接的意思,也就是除了这个单元,外部的单元 也是能够访问这个函数的.static
是内部链接,自属于自己单元. 

说了这么久,还没有说.h的作用呢? 其实没有.h也能很好的工作,但是当你发现一个外部链接的函数或外部变量,需要许多份
声明,因为c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才 知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译单元,会自动从另一个 编译单元那里得到什么信息,知道你是如何定义这个函数的. 所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp里面,这样是不是很麻烦, 而且,如果要修改,就必须一个一个修改.这真让人受不了. .h就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该函数的.cpp,只需要 用#include包含进去便可.以后需要修改,也只是修改一份内容.
请注意不要滥用.h,.h里面不要写代码,.h不是.cpp的仓库,什么都塞到里面. 如果在里面写代码,当其他.cpp包含他的时候,就会出现重复定义的情况, 比如将函数func(){printf};放到头文件a.h,里面还有一些a.cpp需要的声明等; 然后你发现b.cpp需要用到a.cpp里面的一个函数,就很高兴的将a.h包含进来. 注意,#include并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝 进来. 这时候实际上a.cpp和b.cpp都有一个func()函数的定义. 如果这个函数是内部链接static的话,还好,浪费了一倍空间;
如果是extern,外部链接(这个是默认情况),那么根据在同一个程序内不可出现 同名函数的要求,连接器会毫不留情给你一个连接错误! ;如果你还不太理解.那么就尝试不用h,只用多个cpp看看应该如何写. 尝试在两个cpp中写同名函数.看看是否链接出错. 尝试在cpp使用其他cpp定义的函数.看看应该如何做.

头文件是没有编译意义的,一般只是编译.cpp生成.obj. 但是.cpp里面有#include将指定头文件(其实任何文件都行)插进来,组成完整的.cpp.
如果你不喜欢这个方式,你也可以直接在.cpp里面写好了,而不放到.h里面,载用指令 拷贝进来. 头文件是工具,但不是必须.

抱歉!评论已关闭.