当前位置: 首页 > news >正文

【C/C++】程序的构建(编译)过程概述

🦄个人主页:小米里的大麦-CSDN博客

🎏所属专栏:C++_小米里的大麦的博客-CSDN博客

🎁代码托管:C++: 探索C++编程精髓,打造高效代码仓库 (gitee.com)

⚙️操作环境:Visual Studio 2022

目录

一、前言

二、预处理(Preprocessing)

三、编译(Compilation)

四、汇编(Assembly)

五、链接(Linking)

总结 

各阶段输出总结

流程总结

共勉


一、前言

每个语言和环境都有其特定的构建和执行流程,但大多数都会涉及某种形式的处理,将源代码转换成机器可以直接理解的形式。在编译和构建一个 C/C++ 程序的过程中,通常会经过 预处理编译汇编链接 这四个阶段,这个过程被称为构建流程或者编译流程。每个阶段都负责将代码从一个形式转换为下一个形式,最终生成可执行文件。下面我会以一个简单的C/C++程序详细讲解每个阶段的具体过程。

注意:编译器的工作其实非常复杂,远远不是博主我这轻描淡写的两句话就能描述清楚的!想要深入了解,还需不断钻研!!!

二、预处理(Preprocessing)

预处理阶段是编译过程的第一个步骤,主要负责对代码进行宏替换、头文件展开、条件编译等操作。这一阶段的任务是将代码进行格式化标准化,方便后续的编译步骤。

  • 头文件展开#include 指令引入的头文件会被展开,将头文件中的内容插入到文件中。
  • 宏替换:预处理阶段会替换所有的宏定义,例如 #define MAX 100,在代码中使用 MAX 的地方都会被替换为 100
  • 条件编译:根据 #ifdef#ifndef 等预处理指令,编译器会有选择地包含或忽略某些代码。
  • 删除注释:所有的代码注释(///* ... */)会在预处理阶段被移除,代码中只会保留实际的指令。

输出:经过预处理的源文件会生成一个新的文件,通常扩展名为 .i,这就是纯净的、展开后的源代码文件。

例如:

#include <stdio.h>
#define PI 3.14
int main() {printf("%f\n", PI);//打印PI的值
}

预处理后:

int main() {printf("%f\n", 3.14);
}

三、编译(Compilation)

编译器会将预处理后的源代码(.i 文件)转化为汇编代码。这一阶段会对代码的语法进行检查,确保没有语法错误,并且会生成与硬件无关的汇编语言代码。

  • 语法分析:编译器会检查代码的语法,确保代码符合 C/C++ 语言规范。如果语法有问题,编译器会抛出错误。
  • 语义分析:编译器会检查变量类型、函数调用等,确保它们的使用是正确的。
  • 生成汇编代码:编译器会将源代码转换成一种与 CPU 架构无关的汇编代码。这个文件通常以 .s 作为后缀。

输出:经过编译后的文件通常以 .s 为后缀,它包含的是汇编代码。

例子(生成的汇编代码部分,大致是这样,会有部分不准确):

movl $0, %eax
call printf

四、汇编(Assembly)

在汇编阶段,汇编器会将汇编代码(.s 文件)转换成机器代码(即二进制指令)。这些二进制指令可以直接被计算机的处理器执行。

  • 汇编器会将汇编语言翻译成机器指令,这些指令以二进制格式存储在目标文件(.o.obj)中。
  • 目标文件是不可执行的,它只是包含了机器代码和一些符号信息(如变量、函数名等),供下一步的链接使用。

输出:这个阶段的输出是一个目标文件,通常以 .o.obj 作为后缀,里面包含了二进制机器代码。

五、链接(Linking)

链接是编译过程的最后一步,负责将一个或多个目标文件(.o 文件)合并,生成一个可执行文件。这个阶段包括以下几项工作:

  • 符号解析:链接器会解析每个目标文件中的符号(如函数和变量),并将它们正确地关联在一起。比如,如果一个目标文件调用了一个在另一个目标文件中定义的函数,链接器会负责将它们连接起来。
  • 库链接:链接器会将程序需要的库文件(如标准库 libc)与目标文件链接在一起,确保程序能调用库函数。
  • 地址分配:链接器会为每个符号(函数、变量)分配内存地址,使得程序在执行时可以正确访问它们。

输出:链接后的最终产物是一个可执行文件,通常命名为 a.out(在 Linux/Unix 系统中)或 .exe 文件(在 Windows 系统中)。

例子:链接后,生成的可执行文件可以直接运行,执行程序逻辑。

下面放几张图片使抽象的理解形象些:

 

总结 

各阶段输出总结

  • 预处理(Preprocessing):生成预处理后的源代码文件,通常扩展名为 .i
  • 编译(Compilation):生成汇编代码文件,通常扩展名为 .s
  • 汇编(Assembly):生成目标文件,通常扩展名为 .o.obj
  • 链接(Linking):生成可执行文件,扩展名为 a.out(Linux/Unix)或 .exe(Windows)。

流程总结

  1. 预处理:对代码做初步的处理,如头文件展开、宏替换等。
  2. 编译:将预处理后的代码转化为汇编代码,同时进行语法检查。
  3. 汇编:将汇编代码转换为机器代码,生成目标文件。
  4. 链接:将目标文件与库文件链接,生成可执行程序。

这个编译过程将源代码逐步转化为计算机可以执行的二进制机器代码,是 C/C++ 编译过程的核心。

共勉

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • PyAutoGUI:自动化操作的强大工具
  • 【Android Studio】app:compileDebugJavaWithJavac FAILED解决办法
  • c++类型转换
  • GoPlantUML,go代码到类图
  • 33.递归、搜索、回溯之记忆化搜索
  • 2024 年最佳 Chrome 验证码扩展,解决 reCAPTCHA 问题
  • 秋招突击——9/10、9\11——算法练习——携程笔试练习——2024年秋招第一批笔试
  • MYSQL数据库——MYSQL管理
  • 鸿蒙开发入门day19-使用NDK接口构建UI(二)
  • qt使用对数坐标的例子,qchart用QLogValueAxis坐标不出图解决
  • 第J3-1周:DenseNet算法 实现乳腺癌识别(pytorch)
  • 【Echarts】vue3打开echarts的正确方式
  • 惬意享受阅读,优雅的微信公众号订阅方式,极空间部署『WeWe RSS』
  • C++函数在库中的地址
  • java面向对象:构造方法
  • JS 中的深拷贝与浅拷贝
  • 「译」Node.js Streams 基础
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • 0x05 Python数据分析,Anaconda八斩刀
  • Brief introduction of how to 'Call, Apply and Bind'
  • ComponentOne 2017 V2版本正式发布
  • GitUp, 你不可错过的秀外慧中的git工具
  • Git初体验
  • gulp 教程
  • java2019面试题北京
  • JAVA并发编程--1.基础概念
  • laravel5.5 视图共享数据
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • SpiderData 2019年2月25日 DApp数据排行榜
  • springboot_database项目介绍
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • Yii源码解读-服务定位器(Service Locator)
  • 关于extract.autodesk.io的一些说明
  • 猴子数据域名防封接口降低小说被封的风险
  • 你真的知道 == 和 equals 的区别吗?
  • 漂亮刷新控件-iOS
  • 微信小程序:实现悬浮返回和分享按钮
  • 微信小程序实战练习(仿五洲到家微信版)
  • 一个JAVA程序员成长之路分享
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 异常机制详解
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • # 职场生活之道:善于团结
  • #、%和$符号在OGNL表达式中经常出现
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (35)远程识别(又称无人机识别)(二)
  • (附源码)php投票系统 毕业设计 121500
  • (十六)一篇文章学会Java的常用API
  • (学习日记)2024.01.09
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)我也是一只IT小小鸟
  • .NET 的静态构造函数是否线程安全?答案是肯定的!