(C语言) 8大翻译阶段

(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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/62324.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php反序列化1_常见php序列化的CTF考题

声明&#xff1a; 以下多内容来自暗月师傅我是通过他的教程来学习记录的&#xff0c;如有侵权联系删除。 一道反序列化的CTF题分享_ctf反序列化题目_Mr.95的博客-CSDN博客 一些其他大佬的wp参考&#xff1a;php_反序列化_1 | dayu’s blog (killdayu.com) 序列化一个对象将…

Spring Boot拦截器(Interceptor)详解

拦截器Interceptor 拦截器我们主要分为三个方面进行讲解&#xff1a; 介绍下什么是拦截器&#xff0c;并通过快速入门程序上手拦截器拦截器的使用细节通过拦截器Interceptor完成登录校验功能 1. 快速入门 什么是拦截器&#xff1f; 是一种动态拦截方法调用的机制&#xff…

从入门到精通:Java异常处理的最佳实践全解

目录 一、理解异常的分类 二、精简异常处理逻辑 三、合理使用finally块 四、避免吞掉异常 五、记录异常 六、自定义异常提高可读性 七、谨慎使用try-catch块 八、重抛异常并添加上下文 总结 在Java中&#xff0c;异常处理是保障程序稳定性和可靠性的重要部分。尽管Java…

Centos Linux 服务器 批量替换文件内容sed

Centos Linux 服务器 批量替换文件内容sed sed -i "s/oldString/newString/g" grep -rl "oldString" ./

使用 Go 语言中的 Context 取消协程执行

使用 Go 语言中的 Context 取消协程执行 在 Go 语言中&#xff0c;协程&#xff08;goroutine&#xff09;是一种轻量级的线程&#xff0c;非常适合处理并发任务。然而&#xff0c;如何优雅地取消正在运行的协程是一个常见的问题。本文将通过一个具体的例子来展示如何使用 con…

使用zabbix监控k8s

一、 参考文献 小阿轩yx-案例&#xff1a;Zabbix监控kubernetes云原生环境 手把手教你实现zabbix对Kubernetes的监控 二、部署经验 关于zabbix监控k8s&#xff0c;总体来说是分为两块内容&#xff0c;一是在k8s集群部署zabbix-agent和zabbix- proxy。二是在zabbix进行配置。…

GitCode 平台设置访问令牌 从而git仓库(附pycharm创建版本控制项目)

GitCode 背靠CSDN搞了国产的git平台&#xff0c;但在实际使用过程中&#xff0c;我直接感受就是坑爹&#xff01;在查找用户令牌&#xff08;账号密码&#xff09;这一基本功能上&#xff0c;因为是csdn直接登录跳转过去的用户令牌&#xff0c;没有设置过密码&#xff0c;默认就…

ClamAV 在 CentOS 的开发版本 `clamav-devel`

是的&#xff0c;ClamAV 在 CentOS 上有开发版本&#xff08;通常称为 clamav-devel&#xff09;&#xff0c;它包含了开发 ClamAV 应用程序所需的头文件和库文件。以下是如何在 CentOS 上安装 ClamAV 及其开发版本的步骤。 ### 1. **安装 EPEL 仓库** ClamAV 通常在 EPEL&am…

go编程中yaml的inline应用

下列代码&#xff0c;设计 Config 和 MyConfig 是为可扩展 Config&#xff0c;同时 Config 作为公共部分可保持变化。采用了匿名的内嵌结构体&#xff0c;但又不希望 yaml 结果多出一层。如果 MyConfig 中的 Config 没有使用“yaml:",inline"”修饰&#xff0c;则读取…

嵌入式MCU常见问题分类汇总

目录 1.系统 1.1 什么是BSP 嵌入式BSP介绍-CSDN博客 2.数据 2.1 串口数据处理&#xff08;字符转换为十进制数值&#xff09; 关于串口数据处理&#xff08;字符转换为十进制数值&#xff09;-CSDN博客 3.文件 3.1 hex转bin方法 hex转bin方法_lua hex转为bin-CSDN博客

神经网络入门实战:(五)本地数据集的读取,以及从pytorch官网下载数据集的操作

本地带标签图片数据集的读取 代码里面的注释写的都比较清楚&#xff0c;也有拓展的部分&#xff0c;这里就不详细列出。 from torch.utils.data import Dataset # 从torch.utils.data导入Dataset类&#xff0c;用于创建自定义的数据集类 from PIL import Image #引入PIL库中的I…

【Maven】继承和聚合

5. Maven的继承和聚合 5.1 什么是继承 Maven 的依赖传递机制可以一定程度上简化 POM 的配置&#xff0c;但这仅限于存在依赖关系的项目或模块中。当一个项目的多个模块都依赖于相同 jar 包的相同版本&#xff0c;且这些模块之间不存在依赖关系&#xff0c;这就导致同一个依赖…

【C++打怪之路Lv16】-- map set

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;重生之我在学Linux&#xff0c;C打怪之路&#xff0c;python从入门到精通&#xff0c;数据结构&#xff0c;C语言&#xff0c;C语言题集&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持…

Python爬虫爬取数据报错

报错&#xff1a; Error fetching the URL: (Connection aborted., ConnectionResetError(10054, 远程主机强迫关闭了一个现有的连接。, None, 10054, None)) 报错原因&#xff1a; 目标服务器限制&#xff1a; 目标网站可能已经检测到你的请求来自自动化工具&#xff08;如爬虫…

【Linux】线程的互斥和同步

【Linux】线程的互斥和同步 线程间的互斥 临界资源&#xff1a;多线程执行共享的资源就叫做临界资源临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界区&#…

c++设计模式模块与系统

c 中lambda 本质就是一个匿名(没有名)的函数&#xff1b; 可以用一个数组元素存储一个函数的指针&#xff1b; 通过数组下标来使用函数&#xff1b; 高内聚低耦合 如何理解设计模式中的高内聚低耦合 高内聚: 用于指导如何组织和划分软件设计。 **定义&#xff1a;**高内聚指的…

抓包之查看http basic auth认证方式

写在前面 在这篇文章中我们看了http basic auth的认证方式&#xff0c;本文通过wireshark抓包的方式来验证http协议的交互过程。 1&#xff1a;正文 首先wireshark抓取本机回环地址&#xff08;具体看你服务情况&#xff0c;决定哪个网卡&#xff0c;我本地是运行在127的&am…

网络安全(1)_对称加密和非对称加密

1 网络安全概述 1.1 计算机网络面临的安全威协 &#xff08;1&#xff09;截获&#xff1a;攻击者从网络上窃听他人的通信内容&#xff0c;通常把这类攻击称为“截获”。在被动攻击中&#xff0c;攻击者只是观察和分析某一个协议数据单元&#xff08;PDU&#xff09;而不干扰信…

CentOS上如何离线批量自动化部署zabbix 7.0版本客户端

CentOS上如何离线批量自动化部署zabbix 7.0版本客户端 管理的服务器大部分都是CentOS操作系统&#xff0c;版本主要是CentOS 7。因为监控服务器需要&#xff0c;要在前两天搭建的Zabbix 7.0系统上把这些CentOS 7系统都监控起来。因为服务器数量众多&#xff0c;而且有些服务器…

vmware中所有虚拟机都ping不通时解决方案

文章目录 1、报错内容&#xff1a;2、 报错原因&#xff1a;3、解决方案&#xff1a; 1、报错内容&#xff1a; 2、 报错原因&#xff1a; DNS解析错误。 一个虚拟机ping不通可能是网关配置问题&#xff0c;但我的网关配置也都没问题&#xff0c;而且我的所有虚拟机都ping不通…