一、编译过程
1、c++中编译不一定是从main函数开始。
2、C++应用程序的编译过程分为三个阶段。
在cpp文件中展开include文件。
将每个cpp文件编译为一个对应的obj文件。
连接obj文件成为一个exe文件(或者其它的库文件)。
3、一个C++工程中会存在cpp文件,头文件,库文件。
4、预处理过程,将头文件加载进来,并且将各种#define信息代入。这时会见
不到头文件,工程经过处理后会生成以cpp文件为基础的编译单元。
5、关于cpp文件的连接,每个cpp就是一个编译单元,每个编译单元相互之间是独立且相互不知的。一个编译单元(Translation Unit)是指一个.cpp文件以及这所include的所有.h文件,.h文件里面的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件,后者拥有PE(Portable Executable,即Windows可执行文件)文件格式,并且本身包含的就是二进制代码,但是不一定能执行,因为并不能保证其中一定有main函数。当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后,再由链接器进行链接成为一个.exe或.dll文件。
6、在编译单元生成之后,便是将编译单元进行编译,其实对于主流的编译其实存在两个阶段,首先是生成汇编语言,然后使用汇编器生成机器语言。其实这里要讲解的是汇编语言怎么变成机器语言的呢。机器语言顾名思义就是0101的二进制代码。
二、名词解释与注意事项
1、编译器将源文件编译成汇编代码,然后由汇编器 (assembler) 翻译成机器指令 ( 再加上其它相关信息 ) 后输出到一个个目标文件 (object file, VC 的编译器编译出的目标文件默认的后缀名是 .obj) 中;
2、链接器 (linker) 将一个个的目标文件 ( 或许还会有若干程序库 ) 链接在一起生成一个完整的可执行文件。
3、 extern:这就是告诉编译器,这个变量或函数在别的编译单元里定义了,也就是要把这个符号放到未解决符号表里面去。
static:如果static位于全局函数或者全局变量的声明前面,表明该编译单元不导出这个函数或变量,因此这个符号不能在别的编译单元中使用。
4、.h叫做头文件,它是不能被编译的。“#include”叫做编译预处理指令,可以简单理解成,在1.cpp中的#include"1.h"指令把1.h中的代码在编译前添加到了1.cpp的头部。每个.cpp文件会被编译,生成一个.obj文件,然后所有的.obj文件链接起来你的可执行程序就算生成了。
5、.h文件和cpp文件也就是说,在h文件中声明Declare,而在cpp文件中定义Define。 “声明”向计算机介绍名字,它说,“这个名字是什么意思”。而“定义”为这个名字分配存储空间。无论涉及到变量时还是函数时含义都一样。无论在哪种情况下,编译器都在“定义”处分配存储空间。对于变量,编译器确定这个变量占多少存储单元,并在内存中产生存放它们的空间。对于函数,编译器产生代码,并为之分配存储空间。函数的存储空间中有一个由使用不带参数表或带地址操作符的函数名产生的指针。定义也可以是声明。如果该编译器还没有看到过名字A,程序员定义int A,则编译器马上为这个名字分配存储地址。声明常常使用于extern关键字。如果我们只是声明变量而不是定义它,则要求使用extern。对于函数声明, extern是可选的,不带函数体的函数名连同参数表或返回值,自动地作为一个声明。