首页 > 编程知识 正文

编译程序用来干什么,什么是编译?

时间:2023-05-03 12:45:11 阅读:285777 作者:1453

编译到底是在干什么

写c++都知道,写完程序要编译才能形成可执行文件,那么,编译到底是在干一件什么样的事呢?

编译的例子

写一个简单的helloworld.cpp程序

#include<iostream>using namespace std;int main(){ cout<<"hello world!n";}

然后执行g++进行编译并运行:

[root@VM-238-167-centos /]# g++ -o helloworld helloworld.cpp[root@VM-238-167-centos /]# ./helloworld hello world!

实际上,执行g++ -o这个命令,是进行了非常多的步骤的,包括预处理、编译、汇编、链接

编译与链接

预处理

预处理过程主要是处理那些以#开头的预编译指令,包括#include或者#define

可以执行g++ -E生成预处理后的文件,后缀为-i

g++ -E helloworld.cpp -o helloworld.i

查看生成的-i就可以知道将头文件等进行了预编译展开

主要过程如下:

将所有的#define删除,并展开所有的宏定义处理所有条件预编译指令,包括#if、#ifdef、#else等处理#include预编译指令,将被包含的文件插入到预编译指令的位置(递归进行)过滤注释添加行号和文件名标识保留所有的#pragma指令

故如果想查看对应的宏编译是否正确展开时,可以查看预编译后的文件

编译与汇编

编译的过程是进行词法分析、语法分析、语义分析以及优化后产生相应的汇编代码文件。

g++ -S helloworld.i -o helloworld.s

执行后查看该文件可以知道已经产生了对应的汇编文件:

整个编译过程,就是将高级语言翻译为机器语言的过程:通常将其分为6步,包括扫描、词法分析、语义分析、源代码优化、代码生成、目标代码优化。

编译完成后生成了汇编代码,然后编译器将汇编代码转化为机器码,即产生二进制文件

链接

链接的主要任务是将编译好的各个模块进行一个组合,使得各个模块之间能够进行正确衔接。链接的过程主要是:地址和空间的重分配、符号决议、重定位等步骤。

链接分为静态链接和动态链接:

静态链接:对函数库的链接是放在编译时完成的,所有相关的目标文件与牵涉到的函数库被链接合成到一个可执行文件,故函数执行时与库函数再无瓜葛,所有需要的函数都复制到了相关的位置。也就是说,静态链接将所有用到的函数全部链接到exe文件中动态链接:把对库函数的链接载入推迟到程序运行时期。在生成可执行文件时不将所有程序用到的函数链接到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统中找。某个程序在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。

相比之下,静态链接库和动态链接库的特点:

动态链接库更有利于进程间的资源共享动态链接库让程序的升级变得简单。静态库的升级必须重新编译,而动态库的话只要提供给程序的接口没变,则直接用新生成的动态库替代静态库就行动态链接库更加节省内存由于静态库在编译时就将库函数装载到程序中了,动态库是运行时装载,因此用静态库程序运行时速度可能快一些

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。