概述
C++\C源文件,包含.c, .h, .cpp, .hpp等格式的文件,经过预处理、编译、汇编、链接后,形成可执行文件,也就是.exe文件。
以一个简单项目MyProject为例,文件结构如下:
- MyProject
- MyClass.h
- MyClass.cpp
- main.cpp
class MyClass
{
public:
void MyFunction();
}
#include "MyClass.h"
#include <iostream>
void MyClass::MyFunction()
{
std::cout<<"Call MyFunction()";
}
#include "MyClass.h"
int main()
{
MyClass myclass;
myclass.MyFunction();
return 0;
}
其编译流程如下所示,一个cpp就是一个编译单元,h文件在链接时用了多次(故只能用于声明,可以重复声明,但不能重复定义):
一、预处理
预处理阶段主要进行预处理指令的处理,包括: 1.宏定义; 2.文件包含; 3.条件编译。最后产生 .i文件。通常预处理后的文件行数变多,体积膨胀,但还是具有良好的可读性。
- 宏定义
处理 #define ** ** ,又叫宏替换、宏代换,就是宏体替换宏名。
例:
#define PI 3.14
- 文件包含
处理 #include " " ,递归展开文件内容。编译时以包含处理以后的文件为编译单位,一个cpp文件就是一个编译单元,被包含的文件是源文件的一部分,编译以后只得到一个目标文件.obj。
例:
#include<iostream>
#include只是文本包含,任何文本文件都可以包含,与后缀名无关。
如下图,将代码放到 .txt中也可以编译成功。
修改头文件后所有包含该文件的文件都要重新编译。
- 条件编译
使用条件编译可以使目标程序变小,运行时间变短,就是说不满足条件的程序段是不会编译的。可以用于应付不同的编译环境。
例:
#ifdef MYCONDITION
...
#else
...
#endif
二、编译
编译是将源文件转换成汇编代码的过程,具体的步骤主要有:词法分析 -> 语法分析 -> 语义分析及相关的优化 -> 中间代码生成 -> 目标代码生成(汇编代码文件.s)。
代码的规范性和语法错误将在这里检查,检查无误后,生成汇编代码,也就是.s文件。具有汇编基础的同学还是能看一看的。
三、汇编
在汇编阶段,汇编器将之前的汇编代码文件转成可重定位的目标程序,即二进制的目标代码 .o文件,使用文本编辑器打开将是一堆乱码,没有可读性。
目标代码通常有两个段:
四、链接
链接就是将目标文件、启动代码、库文件链接成可执行文件的过程,这个文件可被加载或拷贝到存储器执行。链接可分为静态链接和动态链接:
- 静态链接:将函数实现代码从静态链接库(.lib文件)中拷贝到最终的可执行程序中,程序包含所有的实现,自己就可以完整运行,缺点是体积较大。
- 动态链接:函数实现代码在动态链接库中(.dll文件),链接时只记录所依赖dll的入口信息,运行时需要找到相应的dll文件才能运行。
总结
通常,把整个编译过程分为编译(此“编译”含义更广)和链接两个阶段,前者将源代码编译为目标代码,后者将目标代码链接为可执行程序。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)