IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++编译过程 -> 正文阅读

[C++知识库]c++编译过程

1概述

编译过程:C++\C源文件,包含.c, .h, .cpp, .hpp等格式的文件,经过预处理、编译、汇编、链接后,形成可执行文件,也就是.exe文件。

2主要步骤

源程序(.cpp)-> 预编译处理(.i) -> 编译、优化程序(.s)->汇编程序(.obj、.o、.a、.ko) -> 链接程序(.exe、.elf、.axf等)

2.1.预处理(由cpp文件生成.i文件)

2.1.1预处理指令

大家刚开始写C++语言程序时,肯定看到过这样的指令:
#include <stdio.h>
.h : 头文件扩展名,头文件包含C++函数的声明与宏定义,可被多个源文件中引用共享. 有两种类型的头文件,一种是程序员编写的头文件和编译器自带的头文件,为区别这两种类型的头文件,写法略有不同,如下:
自定义头文件:#include "***.h"
库文件: #include <***.h>
在程序中使用头文件,需要使用C++预处理指令#include来引用它. 前面我们已经看到过stdio.h头文件,它是编译器自带的头文件.
其实预处理指令不仅仅只有#include,如下:(带#的指令,它不是语句,所以不需要在后面加分号)
在这里插入图片描述

2.1.2现在我们来说一下预处理操作到底干了些什么 ?

? 将所有的define删除,并且展开所有的宏定义,也就是:字符替换;
? 处理所有的条件编译指令,#if, #ifdef, #ifudef等;
? 处理#include,递归展开文件内容。将#include指向的头文件插入(复制)到该cpp文件;编译时以包含处理以后的文件为编译单位,一个cpp文件就是一个编译单元,被包含的文件是源文件的一部分,编译以后只得到一个目标文件.obj
? 删除所有注释;
? 添加行号和文件标示,这样的在调试和编译出错时才知道是哪个文件的哪一行;
? 保留#pragma编译指令,因为编译器需要使用它们.

2.2编译(由.i文件生成.s文件)

编译的过程实质是把高级语言翻译为汇编语言的过程,那到底对 .i文件 做了些什么呢?
? 词法分析;
? 语法分析;
? 语义分析;
? 优化后生成相应的汇编代码.
从 高级语言 → 汇编语言

2.3汇编(由.s文件生成.o/obj文件)

其实我们经常把编译和汇编统统说成:编译.
汇编就是将汇编语言转成机器语言
汇编语言 → 机器语言 (二进制)

注:GCC的目标文件(机器码)的后缀是 .o  
Visual C++的目标文件的后缀是 .obj

2.4链接(由.o/obj、lib、dll等文件生成.exe文件)

链接就是将目标文件、启动代码、库文件链接成可执行文件的过程.
链接的作用如下:
? 当源程序很大时,可以将它分为多个源程序,通过编译可以形成多个目标文件(Unix: .o),这时我们需要用链接器把它们连接到一起,生成一个可执行文件;
? 程序中调用了某个库文件中的子程序, 需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件;
? 一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,链接器程序将这些内容处理为最终的可执行信息. 所以,在只有一个源程序文件,而又不需要调用某个库中的子程序时,也必须用链接器对目标文件进行处理,生成可执行文件.

3示例

以一个简单项目MyProject为例,文件结构如下:

MyProject
MyClass.h
MyClass.cpp
main.cpp

//MyClass.h
class MyClass
{
public:
	void MyFunction();
}
//MyClass.cpp
#include "MyClass.h"
#include <iostream>

void MyClass::MyFunction()
{
	std::cout<<"Call MyFunction()";
}
//main.h
#include "MyClass.h"

int main()
{
	MyClass myclass;
	myclass.MyFunction();
	return 0;
}

其编译流程如下所示,一个cpp就是一个编译单元,h文件在链接时用了多次(故只能用于声明,可以重复声明,但不能重复定义)

参考1
参考2

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-15 01:47:57  更:2022-09-15 01:48:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:13:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码