编译过程

简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程:

  • 预处理阶段
  • 词法与语法分析阶段
  • 编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制机器码,生成各个目标文件 (.obj文件)
  • 连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关 的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格 式信 息。(生成.exe文件)

编译器在编译时是以cpp文件为单位进行的,也就是说如果你的项目中一个cpp文件都没有,那么你的项目将无法编译,连接器是以目标文件为单位,它将一个或多个目标文件进行函数与变量的重定位,生成最终的可执行文件,在PC上的程序开发,一般都有一个main函数,这是各个编译器的约定。

举个例子:

#include "mytest.h"int main(int argc,char **argv)
{
test = 25;
printf("test.................%d/n",test);
}mytest.h头文件内容如下:
int test;

现在以这个例子来讲解编译器的工作:
1.预处理阶段:
编译器以cpp文件作为一个单元,首先读这个cpp文件,发现第一句是包含一个头文件,就会在所有搜索路径中寻找这个文件,找到之后,就会将相应头文件中去处理宏,变量, 函数声明,嵌套的头文件等操作,检测依赖关系,进行宏替换,看是否有重复定义与声明的情况发生,最后将h文件中所有的内容全部扫描进这个当前的C文件中,形成一个中间“cpp文件”

2.编译阶段
在上一步中相当于将那个头文件中的test变量扫描进了一个中间cpp文件,那么test变量就变成了这个文件中的一个全局变量,此时就将所有这个中间cpp文件的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件。

3.连接阶段
将上一步成生的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将个目标文件中的二进制码按一定的规范合到一个文件中。

C++头文件和源文件的区别

理论上来说源文件与头文件里的内容,只要是C++语言所支持的,无论写什么都可以的,比如你在头文件中写函数体,只要在任何一个源文件包含此头文件就可以将这个函数编译成目标文件的一部分(编译是以源文件为单位的,如果不在任何源文件中包含此头文件的话,这段代码就形同虚设),你可以在源文件中进行函数声明,变量声明,结构体声明,这也不成问题!!!

那为何一定要分成头文件与C文件呢?为何一般都在头件中进行函数,变量声明,宏声明,结构体声明 呢?而在C文件中去进行变量定义,函数实现呢?
原因如下:
1.如果在h文件中实现一个函数体,那么如果在多个源文件中引用它,而且又同时编译多个源文件,将其生成的目标文件连接成一个可执行文件,在每个引用此头文件的源文件所生成的目标文件中,都有一份这个函数的代码,如果这段函数又没有定义成局部函数,那么在连接时,就会发现多个相同的函数,就会报错。

2.如果在h文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此头文件的源文件中同样存在相同变量名的拷贝,关键是此变量被赋了初值,所以编译器就会将此变量放入DATA段,最终在连接阶段,会在DATA段中存在多个相同的变量,它无法将这些变量统一成一个变量,也就是仅为此变量分配一个空间,而不是多份空间,假定这个变量在头文件没有赋初值,编译器就会将之放入 BSS段,连接器会对BSS段的多个同名变量仅分配一个存储空间 。

3.如果在源文件中声明宏,结构体,函数等,那么我要在另一个源文件中引用相应的宏,结构体,就必须再做一次重复的工作,如果我改了一个源文件中的一个声明,那么又忘了改其它源文件中的声明,这不就出了大问题了,如果把这些公共的东东放在一个头文件中,想用它的C文件就只需要引用一个就OK了!!!这样岂不方便,要改某个声明的时候,只需要动一 下头文件就行了

4.在头文件中声明结构体,函数等,当你需要将你的代码封装成一个库,让别人来用你的代码,你又不想公布源码,那么人家如何利用你的库中的各个函数呢??一种方法是公布源码,别人想怎么用就怎么用,另一种是提供头文件,别人从头文件中看你的函数原型,这样人家才知道如何调用你写的函数,就如同你调用printf函数一样,里面的参数是怎样的??你是怎么知道的??还不是看人家的头文件中的相关声明 啊!!!

总结

头文件和源文件在本质上没有任何区别。 只不过一般:后缀为 .h 的文件是头文件,内含函数声明、宏定义、结构体定义等内容。后缀为 .cpp的文件是源文件,内含函数实现,变量定义等内容。而且是什么后缀也没有关系,只不过编译器会默认对某些后缀的文件采取某些动作。这样分开写成两个文件是一个良好的编程风格。

include的过程完全可以“看成”是一个文件拼接的过程,将声明和实现分别写在h文件及C文件中,或者将二者同时写在头文件中,理论上没有本质的区别。

结合编译过程,分析C++头文件和源文件的区别相关推荐

  1. C++头文件和源文件,编译过程

    源文件如何根据#include来关联头文件  1.系统自带的头文件用尖括号括起来,这样编译器会在系统文件目录下查找. #include <xxx.h> 2.用户自定义的文件用双引号括起来, ...

  2. C++头文件和源文件的编译过程

    源文件如何根据#include来关联头文件 1.系统自带的头文件用尖括号括起来,这样编译器会在系统文件目录下查找. #include <xxx.h> 2.用户自定义的文件用双引号括起来,编 ...

  3. C++ 头文件和源文件

    from:https://www.cnblogs.com/fenghuan/p/4794514.html C++中头文件(.h)和源文件(.cpp)都应该写些什么 头文件(.h): 写类的声明(包括类 ...

  4. 头文件和源文件的关系

    一.关于头文件和源文件之间的关系,理解把握要点在于: 1.头文件是给编程开发人员看的,而源文件是给编译器看的: 2.在#include头文件时,编译器直接把相应的头文件复制粘贴到源文件的相应位置: 3 ...

  5. C++:include:理解 C++ 中的头文件和源文件的作用

    关于头文件和源文件我们主要围绕: C++编译模式, 声明和定义区别, 符号只能被定义一次, 符号被定义在多个源文件,但是一个源文件只能定义一次 这四个方面来分析论述 1:C++ 编译模式 在一个C++ ...

  6. C++ 笔记(25)— 理解 C++ 中的头文件和源文件的作用

    1. C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件: .cpp 文件,被称作 C++ 源文件,里面放的都是 C++ 的源代码 .h 文件,被称作 C++ 头文件,里面放的也是 C++ ...

  7. 【C 语言】编译过程 分析 ( 预处理 | 编译 | 汇编 | 链接 | 宏定义 | 条件编译 | 编译器指示字 )

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  8. C++类模板怎么写在单独的头文件和源文件中

    今天打算研究研究之前我们领导写的一段关于类模板的代码,后来发现有点坑需要记录一下.以往关于C++模板基本上都是写一个demo,然后运行通过,没有软件工程的样子,所以今天我按以往的惯例写了一个类模板,打 ...

  9. C语言头文件和源文件差异,#include两种引用方式差异

    一些初学c语言的人,不知道头文件(*.h文件)原来还可以自己写的.只知道调用系统库函数时,要使用#include语句将某些头文件包含进去.其实,头文件跟.c文件一样,是可以自己写的.头文件是一种文本文 ...

最新文章

  1. 推荐收藏 | 算法工程师常见面试问题及相关资料汇总
  2. 阿里云ESC搭建SVN服务端
  3. python映射类型-Python基础类型之字典(dict)
  4. SAP Spartacus里解析route参数的逻辑
  5. 解决android中Layout文件下的xml文件配好后,R类中不能自动生成相应代码
  6. 我是这样理解HTTP和HTTPS区别的
  7. JAVA程序设计:接受数字并求和
  8. rs485接收中断函数使能_RS485通讯几种常见问题
  9. 敏感词过滤及反垃圾文本的相关知识(欢迎收藏)
  10. javascript 去掉html标签,js怎么去掉html标签
  11. [信息论与编码]离散信源及其信息测度(2)
  12. 图纸设计管理平台,彩虹图纸管理软件设计管理功能
  13. 高并发系统设计:通用的设计方法及架构分层
  14. Power BI 参数解决源文件路径问题
  15. pickle.dump和pickle.load
  16. Linux 网络之ss
  17. 【PWA】web推送技术
  18. Matlab学习-基本介绍
  19. 什么是信息(Information)?
  20. 工业级RS-485隔离中继器放大器模块,WJ100

热门文章

  1. Python程序设计 第1章:初识Python
  2. 基于空间大数据的社会感知
  3. 【深度学习】召回过程优化--BM25
  4. 黄晓明演绎天梭全新海星1000系列机械款腕表
  5. 九江大桥事故鉴定太神奇了!
  6. 基于STM32的智能手表
  7. RTL8762DW手环SDK创建哪些任务
  8. ABAQUS学习记录1——用户子程序综述
  9. 用了PDM,为什么我的文件管理效率并没有明显提高?
  10. 关于python深copy与浅copy的一点理解