1 编译器的工作过程:
1.预处理阶段(头文件的编译)
2.词法与语法分析阶段 (语法检查)
3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件 (.obj文件)
4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息。(生成.exe文件)
Example
#include <stdio.h> #include "mytest.h" int main(int argc,char **argv) { test = 25; printf("test.................%d\n",test);
mytest.h头文件内容如下:
int test;
1.预处理阶段:编译器以C文件作为一个单元,首先读C文件,引入第一行第二行的头文件,就会在所有搜索路径中寻找这两个文件,找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等,检测依赖关系,进行宏替换,看是否有重复定义与声明的情况发生,最后将这些东西和当前C文件做累和,形成一个‘’中间.c文件"(包含原.c和引用的.h文件)。
2. 编译阶段:形成“中间.c文件”后,test变量就变成了这个文件中的一个全局变量,此时编译器将“中间.c文件”的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件。
3.连接阶段:将上一步成生的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将目标文件中的二进制码按一定的规范整合到一个文件中,最终形成可执行文件exe。
2、.c文件与 .h文件各写什么内容?为何要分 .c和.h文件呢?
.h文件是头文件,内含函数声明、宏定义、结构体定义等内容。.c文件是程序文件,内含函数实现,变量定义等内容。
这样分开写成两个文件是一个良好的编程风格,并无实际意义。
3、动态编译和静态编译
动态编译: 上述直接引用是动态编译。
静态编译: 基本所有的C/C++编译器都支持一种链接方式被称为Static Link,即所谓静态链接。在这种方式下,头文件(.h文件), 以及他们对应的实现文件(.cpp文件),编译程序会将其编译为静态的库文件(.lib文件)。在随后的代码重用过程中,我们只需要引用相应的头文件(.h)和相应的库文件(.lib)即可。
相对动态方式而言,静态方式的好处是实现代码的隐蔽性,即C++中提倡的"接口对外,实现代码不可见"。有利于库文件的转发.
tips.
C语言文件后缀必须小写.c,否则编译器gcc会认为为c++文件。