(C语言) 8大翻译阶段

news/2024/12/12 19:10:54

(C语言) 8大翻译阶段

文章目录

  • (C语言) 8大翻译阶段
    • ⭐前言
    • 🗃️8大阶段
      • 🗂️1. 字符映射
      • 🗂️2. 行分割
      • 🗂️3. 标记化
      • 🗂️4. 预处理
      • 🗂️5. 字符集映射
      • 🗂️6. 字符串拼接
      • 🗂️7. 翻译
      • 🗂️8. 链接
    • 🗃️C++ 的 9 大阶段
      • 🗂️实例化模板
    • ⭐END
      • 🌟ref
      • 🌟交流方式

⭐前言

我们常说的C语言编译的4阶段,预处理,汇编,编译,链接

其实这背后有复杂和细分的阶段,将之称为翻译阶段。

而C语言共有8个这样的阶段。

  1. 字符映射
  2. 行分割
  3. 标记化
  4. 预处理
  5. 字符集映射
  6. 字符串拼接
  7. 翻译
  8. 链接

🗃️8大阶段

🗂️1. 字符映射

编译器将物理源文件中的字符转换为编译器可以理解的内部表示。

这通常涉及到字符编码的处理,比如将文件中的UTF-8UTF-16等编码字符统一转换为编译器可识别的源字符集字符集。

注意:在 C23 前需要处理三标符。

源字符集是包含作为单字节子集的基本源字符集的多字节字符集,后者由以下 96 个字符组成:

a) 5 个空白字符(空格、水平制表、垂直制表、换页、换行)
b) 10 个数字字符,从 ‘0’ 到 ‘9’
c) 52 个字母,从 ‘A’ 到 ‘Z’ 以及从 ‘a’ 到 ‘z’
d) 29 个标点字符: _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " ’

🗂️2. 行分割

编译器将物理行转化为逻辑行。

将代码并按行分割,这样每行可以单独进行处理。

在源代码中由反斜杠\结尾(紧跟着换行符),删除反斜杠和换行符号,将下一个物理行连接上来合并为一个逻辑行。

注意:若此步骤后,非空源文件不以换行符结束(无论是原本就无换行,还是以反斜杠结束),则行为未定义。

物理行 (physical line) -> 逻辑行 (logical line)

物理文件

#include <stdio.h>#define PUTS p\
u\
t\
s
/* 行拼接在阶段 2 进行,* 而宏的标记分析是在阶段 3 并在阶段 4 展开,* 因此以上代码等价于 #define PUTS puts*/int main(void)
{/* 用行拼接来调用 puts */ PUT\
S\
("Output ends here\\
0Not printed" /* 行拼接之后,剩余的反斜杠* 转义了 0,提早结束了字符串。*/
);
}

效果

#include <stdio.h>#define PUTS putsint main(void)
{PUTS("Output ends here\0Not printed");
}

🗂️3. 标记化

编译器将源代码分解最小独立单元。

将源文件分解为注释、空白字符(空格、水平制表、换行、垂直制表、换页)序列和下列预处理记号

​ a) 头文件名:<stdio.h>"myfile.h"

​ b) 标识符

​ c) 预处理数字,包括整数常量和浮点常量,但也包括一些非法记号,例如 1…E+3.foo 或 0JBK

​ d) 字符常量与字符串字面量

​ e) 运算符与标点,例如 +、<<=、<% 或 ##。

​ f) 不属于任何其他类别的单独非空白字符

以一个空格字符替换每段注释

保持换行符。是否可将非换行的空白符序列缩减成单个空格字符是实现定义的。

另一种分类法:

Tokens:

The smallest individual units are known as tokens such as keywords, identifiers, strings, operators &

special symbols.

  1. Keywords are the reserved (special) words and can’t be used as variable, functions names.
  2. Identifiers refer to the names of the variables, arrays, functions, classes etc.
  3. Constants refer to fixed values that we cannot change in a program.
  4. String is a group of characters.
  5. Operators are special symbols which operate on variable & constants and form expressions.
  6. Special symbols are () {} [] etc.

🗂️4. 预处理

预处理器对上述的结果进行预处理。

执行预处理器。

#include 指令所引入的每个文件都经历阶段 1 到 4(上述所有阶段),递归执行。

此阶段结束时,从源码移除所有预处理器指令。

🗂️5. 字符集映射

将源字符集转换成执行字符集。

将字符常量及字符串字面量中的所有字符及转义序列从源字符集转换成执行字符集(可为如 UTF-8 的多字节字符集,只要来自阶段 1 中所列的基本源字符集的所有 96 个字符拥有单字节表示)。

注意:若转义序列所指定的字符不是执行字符集的成员,则结果是实现定义的,但保证不是空(宽)字符。

🗂️6. 字符串拼接

连接相邻的字符串字面量。

例如,使用字符串化运算符(#)可以将两个字符串合并。

#include <stdio.h>int main() {const char* str = "Hello" ", " "World";printf(str);
}

最后将输出:Hello, World

🗂️7. 翻译

对每个翻译单元进行翻译。

发生编译:对各个记号进行语法和语义分析,并将它们作为翻译单元完成翻译。

这个阶段将预处理后的源代码转换成中间表示形式,然后进一步转换成目标代码。

这包括语法分析、语义分析、中间代码生成、代码优化和目标代码生成。

🗂️8. 链接

将所有需要的二进制文件连接成一个可执行程序。

发生链接:将翻译单元和满足外部引用所需的库组件到汇集成程序映像,它含有在其执行环境(操作系统)中执行所需的信息。

🗃️C++ 的 9 大阶段

C++ 共 9 个阶段,本质和 C语言 差不多,有一些细节的差异。

最核心的是在翻译和链接之间,有一个实例化模板阶段。

🗂️实例化模板

检验每个翻译单元,产生所要求的模板实例化的列表,其中包括显式实例化所要求的实例化。

定位模板定义,并进行所要求的实例化,以产生实例化单元




⭐END

🌟ref

C 翻译阶段 - cppreference.com

C++ 翻译阶段 - cppreference.com

Effective C 中文版 (豆瓣)

🌟交流方式

关注我,学习更多C/C++,python,算法,软件工程,计算机知识!

⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区

B站

👨‍💻主页:天赐细莲 bilibili


https://dhexx.cn/news/show-5466015.html

相关文章

里氏替换原则:Java面向对象设计的基石

在面向对象编程&#xff08;OOP&#xff09;中&#xff0c;继承是一个强大的工具&#xff0c;它允许我们创建新的类&#xff08;子类&#xff09;来复用和扩展现有类&#xff08;父类&#xff09;的功能。然而&#xff0c;继承也带来了复杂性&#xff0c;特别是在确保子类能够正…

LangGPT社区创始人云中江树:用热爱与坚持点燃实战营课堂

书生大模型实战营第 4 期正在火热进行中&#xff0c;在这里&#xff0c;我们见证了众多同学的成长与进步。今天&#xff0c;让我们一起走进第 4 期导师、结构化提示词 LangGPT 社区创始人云中江树的故事。他的故事不仅是对知识改变命运的生动诠释&#xff0c;更是一段关于热爱与…

Unity3D模型场景等测量长度和角度功能demo开发

最近项目用到多段连续测量物体长度和角度功能&#xff0c;自己研究了下。 1.其中向量角度计算&#xff1a; 需要传入三个坐标来进行计算。三个坐标确定两条向量线段的方向&#xff0c;从而来计算夹角。 public Vector3 SetAngle(Vector3 p1, Vector3 p2,Vector3 p3) { …

大数据新视界 -- 大数据大厂之 Hive 数据安全:加密技术保障数据隐私(下)(16/ 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

FLASH分区---FAT分区添加操作

1、板卡配置 注意&#xff1a;使用fat文件系统的时候&#xff0c;必须download进去一个fat系统的镜像 fat.img 0xee0000 注意&#xff1a;需要打开fat宏定义&#xff08;涉及到底层&#xff0c;必须开&#xff0c;否则无法创建文件&#xff09; 2、板卡.c 配置 修改分区大小、增…

uniapp的video组件截图(抓拍)功能,解决截后为黑图bug

废话不多说先上代码&#xff01;&#xff01;&#xff01;&#xff01; 点击截图按钮触发以下方法 getCapture() {let _this thislet pages getCurrentPages();let page pages[pages.length - 1];let ws page.$getAppWebview();let bitmap new plus.nativeObj.Bitmap(te…

初窥 HTTP 缓存

引言 对于前端来说, 你肯定听说过 HTTP 缓存。 当然不管你知不知道它, 对于提高网站性能和用户体验, 它都扮演着重要的角色! 它通过在客户端和服务器之间存储和重用先前获取的资源副本, 来减少网络流量和降低资源加载时间, 从而提升用户体验! 以下是 HTTP 缓存的重要性: 减少…

C++实现网格交易的例子

网格交易是一种投资策略&#xff0c;它通过在预设的价格区间内自动进行买入和卖出操作来捕捉市场的波动收益。以下是网格交易的一些详细介绍&#xff1a; 定义&#xff1a; 网格交易策略是一种围绕基准价进行的交易方法&#xff0c;每当价格下跌时&#xff0c;在触发点位执行买…

【docker】docker的起源与容器的由来、docker容器的隔离机制

Docker 的起源与容器的由来 1. 虚拟机的局限&#xff1a;容器的需求萌芽 在 Docker 出现之前&#xff0c;开发和部署软件主要依赖虚拟机&#xff08;VMs&#xff09;&#xff1a; 虚拟机通过模拟硬件运行操作系统&#xff0c;每个应用程序可以运行在自己的独立环境中。虽然虚…

云技术基础(泷羽sec)

声明 学习视频来自B站UP主 泷羽sec,如涉及侵泷羽sec权马上删除文章。 笔记只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 这节课旨在扩大自己在网络安全方面的知识面&#xff0c;了解网络安全领域的见闻&#xff0c;了…