(C语言) 8大翻译阶段

(C语言) 8大翻译阶段

文章目录

  • [(C语言) 8大翻译阶段](#(C语言) 8大翻译阶段)
    • ⭐前言
    • 🗃️8大阶段
      • [🗂️1. 字符映射](#🗂️1. 字符映射)
      • [🗂️2. 行分割](#🗂️2. 行分割)
      • [🗂️3. 标记化](#🗂️3. 标记化)
      • [🗂️4. 预处理](#🗂️4. 预处理)
      • [🗂️5. 字符集映射](#🗂️5. 字符集映射)
      • [🗂️6. 字符串拼接](#🗂️6. 字符串拼接)
      • [🗂️7. 翻译](#🗂️7. 翻译)
      • [🗂️8. 链接](#🗂️8. 链接)
    • [🗃️C++ 的 9 大阶段](#🗃️C++ 的 9 大阶段)
    • ⭐END

⭐前言

我们常说的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)

物理文件

c 复制代码
#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,提早结束了字符串。
               */
);
}

效果

c 复制代码
#include <stdio.h>

#define PUTS puts

int 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. 字符串拼接

连接相邻的字符串字面量

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

c 复制代码
#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

相关推荐
杯莫停丶4 小时前
设计模式之:模板模式
开发语言·设计模式
开发者小天4 小时前
调整为 dart-sass 支持的语法,将深度选择器/deep/调整为::v-deep
开发语言·前端·javascript·vue.js·uni-app·sass·1024程序员节
老猿讲编程5 小时前
C++中的奇异递归模板模式CRTP
开发语言·c++
Yupureki6 小时前
从零开始的C++学习生活 16:C++11新特性全解析
c语言·数据结构·c++·学习·visual studio
落落鱼20137 小时前
Dompdf库html生成pdf时editor编辑器中文本长度被截断不会自动换行问题处理
pdf·编辑器·php·html生成pdf
紫荆鱼7 小时前
设计模式-迭代器模式(Iterator)
c++·后端·设计模式·迭代器模式
汤姆yu7 小时前
基于python的化妆品销售分析系统
开发语言·python·化妆品销售分析
ScilogyHunter7 小时前
C语言标准库完全指南
c语言·开发语言
sali-tec7 小时前
C# 基于halcon的视觉工作流-章52-生成标定板
开发语言·图像处理·人工智能·算法·计算机视觉
应茶茶7 小时前
C++11 核心新特性:从语法重构到工程化实践
java·开发语言·c++