123456

 

VC编译过程

首先是预编译(当然是编译之前做点准备工作了!)

     常见的预编译指令有:

(1)#include 指令,该指令指示编译器将xxx.xxx文件(.h或.cpp都可以,不要以为只有.h能#include)的全部内容插入此处,

(2)#define指令 也就是宏展开了

(3)#if、#else和#endif指令 在头文件中主要是避免重复调用 (比如说两个头文件互相包含对方)

当然也可以用#pragma once,

其次是编译

     编译是以一个个独立的文件作为单元的,一个文件就会编译出一个目标文件。(这里插入一点关于编译的文件的说明,编译器通过后缀名来辨识是否编译该文件,因此“.h”的头文件一概不理会,而“.cpp”的源文件一律都要被编译,我实验过把test.h文件的后缀名改为test1.cpp,然后在include的地方相应的改为test1.cpp,这样一来,编译器就会编译出一个test1.obj,只不过头文件里我们通常只放置声明而不是定义,因此最后链接生成的可执行文件的大小是不会改变的)清楚编译是以一个个单独的文件为单元的,这一点很重要,因此编译只负责本单元的那些事,而对外部的事情一概不理会,在这一步里,我们可以调用一个函数而不必给出这个函数的定义,但是要在调用前得到这个函数的声明(其实这就是include的本质,不就是为了给你提前提供个声明而好让你使用吗?至于那个函数到底是如何实现的,需要在链接这一步里去找函数的入口地址。因此提供声明的方式可以是用include把放在别的文件中的声明拿过来,也可以是在调用之前自己写一句void max(int,int);都行,编译阶段剩下的事情就是分析语法的正确性之类的工作了。好啦,总结一下,可以粗略的认为编译阶段分两步:第一步,检验函数或者变量是否存在它们的声明;第二步,检查语句是否符合C++语法。

最后一步是链接

    它会把所有编译好的单元全部链接为一个整体文件,其实这一步可以比作一个连线的过程,比如A文件用了B文件中的函数,那么链接的这一步会建立起这个关联。链接时最重要的我认为是检查全局空间里面是不是有重复定义或者缺失定义,这也就解释了为什么我们一般不在头文件中出现定义,因为头文件有可能被释放到多个源文件中,每个源文件都会单独编译,链接时就会发现全局空间中有多个定义了。

 

 

http://www.vckbase.com/document/viewdoc/?id=1591

posted on 2011-05-24 11:33  hgy413  阅读(232)  评论(0编辑  收藏  举报

导航