程序编译的4个过程(记录贴,学渣学习两月半c++练习生第一次blog,若有错误请提出)
在使用编译器编译一段程序时,当我们编辑完成之后,只需要点击编译键,则编译器则会返回对这段程序的编译结果,如果错误则返回错误的地方以及错误提示,方便我们对此处的程序进行修改,而使程序可以完成编译。但是我们是否曾纠结过编译器在编译的时候是一个什么样的过程。我们只知道此段程序,函数在编译的时候一共分为四个阶段:
1.预编译;
2.编译;
3.汇编;
4.链接;
先来看一段代码:
#include<stdio.h>
int main()
{
printf("hello c world!");
return 0;
}
这是绝大多数人在学习IT的时候写的第一段代码,让我们来通过此段代码来熟悉编译器对代码编译的整个过程!
1.预编译
每次写c语言的时候,我们都会写#include<stdio.h>等等以#include<>开头的一段代码,而预编译的目的就是解读类似的代码,将此类头文件进行处理,类似于其他的宏定义。同时,我们在进行编写代码的注释,通过预编译则可以则可以对这些对于代码编译无关紧要的东西进行处理。等到预编译完成之后,将会生成 hello.i 的源文件。
预编译的规则:
- 删除所有的“#define”,并且展开宏定义;
- 处理所有的条件预编译的指令:“#if” “#ifdef” “#elif” “#else” “ #endif”等等;
- 删除所有的注释;
- 添加行号和文件名标识;
- 处理所有的 #include头文件引用;
- 保留所有的 #pragma编译器指令;
2.编译
编译的过程主要是把预处理完的的文件进行一系列词法分析、语法分析、语义分析以及产生汇编文件代码(.O)。 进行语法分析,并判断语法的对错,并且给出提示。一段代码是否能够编译通过的命运则几乎全部掌握在这一阶段。而函数的编译过程,则是从上往下进行,而不是函数执行时先从main()函数开始,所以这样也会经常有刚入坑的人犯一些错误。来,见代码:
#include<stdio.h>
int add(int x,int y)
{
return max=x+y;
}
int main()
{
int max,c;
int a=10;
int b=20;
printf("%d \",add(a,b));
return 0;
}
来点击编译康康是什么结果,结果奉上:
由于编译器编译的时候是自上往下编译,所以在运行add()函数内的时候编译器检查到max在之前的编译过程中,并没有遇到,所以直接杀掉了判了这段程序死刑。即使在最重要的主程序中,已经定义过max,但是由于max的可见性只在主函数内,并未延伸到add()函数中,所以这段程序编译失败。(有没有注意到引入了可见性概念,回头再说)
3. 汇编
对于这一过程,便是编译器最强大功能体现的时候,把我们人类达成一直标准的语言转换成机器能读懂的汇编语言,实现真正的人机交互。也完成两个完全不同的个体之间的交流翻译,使计算机成为开发者手中的工具。
4.链接
对于一个庞大的工程文件,功能的实现是通过多个.cpp文件或者.c文件来共同完成,不同的函数来完成不同的功能,然后通过链接过程来把各个模块组装起来,来完成最后一步,于是乎,就生成了hello.exe文件。可以运行的文件便可以使用,则就等开发者点击运行,代码的结果就可以正常执行。