编译器是一种计算机程序,可将代码从一种编程语言(源语言)转换为另一种编程语言(目标语言)。
编译器可用于将高级源代码转换为低级目标代码(如汇编语言、目标代码或机器代码),同时保留程序的功能。
编译器是现代实用计算机编程的重要工具,可支持程序员使用人类可读的高级代码,并将其源代码转换为可执行的目标代码。编译器还可以帮助软件开发人员创建具备更高安全性、稳定性和可移植性的高效可执行程序。这是因为编译器有助于识别和解决错误,从而创建可移植的可执行应用程序。
虽然所有编译器都能将高级代码转换为低级可执行代码,但各类编译器所对应的编程语言和应用场景也各不相同。例如,交叉编译器用于针对与其运行环境不同的 CPU 或操作系统生成代码。
当理想的编译器不可用或尚未构建时,临时的 bootstrap 编译器就会被用来编译更永久的编译器,以便更好地优化特定编程语言的编译。
其他相关软件的简要列表包括:
实际上,编译器的操作非常简单,只需在任何 Linux (或同等)系统的命令行中输入命令,即可指定编译器可执行文件和要编译的源文件。该命令可指示系统处理源代码,将其编译成目标机器代码,并生成必要的目标文件,从而生成可执行程序。
开源编译器(如 GNU 编译器套件 (GCC) 这一强大的 C 编译器组合)通常用于将 C 代码编译为 C 程序,Clang 等替代工具则可通过 GitHub 等资源库获取。其他编译器可以自由安装或从众多经销商处购买。它们还能内置于主流集成开发环境 (IDE),以绑定各种软件开发实用程序,包括文本编辑器、API 文档和调试工具。
无论使用哪种特定的编译器,编译代码的过程都涉及使源代码经过各个级别的分析、优化和最终的代码生成。源代码按顺序通过不同的分析层,并通过流程中的每个步骤进行评估。
如果编译器发现源代码存在任何问题,它可能会返回一条错误消息,提示开发人员在继续编译其余代码之前解决已识别的错误。一般来说,编译器通过以下步骤进行编译:
部分编译器可能不会严格遵守上述结构。不过,虽然某些编译器所包含的步骤或多或少,但编译的所有阶段均可归为以下三个阶段:前端、中端和后端。
这种三段式结构可支持编译器采用模块化方法。它允许编译器将适用于不同语言的多个前端与不同 CPU 的后端相结合,同时共享相应中间端的优化功能。
编译器的三个阶段涉及以下分发:
虽然编译器并不是生成可用代码的明确必要条件,但编码语言和机器环境的广泛多样性和复杂性使得编译器成为创建可执行软件的实际必需品。以下是使用软件编译器的四个主要优点。
高级编程语言使用的语法和关键字更接近口语,因此开发人员更容易使用。编译器将这种人类可读的代码转换为运行优化的软件应用程序所需的更复杂的机器代码。
高级语言的一些示例包括以下语言:
编译器通过将高级代码转换为可执行的机器代码来帮助提高效率。编译器的输出以 .exe 文件扩展名存储,然后由计算机直接执行。由于编译器的存在,编写可执行程序成为一项一次性的任务。
编译完成后,可根据需要多次执行编译后的代码。此过程通常可帮助程序更快、更高效地运行,因为某些应用程序或应用程序的某些部分可以与运行时软件任务分开执行。
并非所有系统都可以运行所有类型的编程代码。编译器用于将开发人员喜欢使用的代码类型转换为系统运行所需的代码类型。通过这种方式,编译器通过将软件转换为多种兼容语言来提高程序可移植性;这些语言可以在各种操作系统和硬件架构中轻松存储、传输和执行。
在编译过程中,编译器可用于识别和解决软件错误和缺陷,从而使程序更加稳定和优化。编译器还可以通过防止与内存相关的错误(例如缓冲区溢出)来帮助提高软件安全性,并在检测到潜在的内存问题时生成警告。
编译器用于将源代码转换为可执行机器代码,而解释器是另一种可以提供类似功能但机制不同的程序。
解释器不会转换源代码,而是直接执行源代码或使用称为中间代码。此代码又称“字节码”,是独立于平台的源代码低级表示形式。字节码可充当人类可读源代码和机器代码之间的中介,专为虚拟机 (VM) 执行而设计,而非基于计算机硬件运行。
理论上,任何编程语言都可以通过编译器或解释器来执行。然而,个别编程语言往往更适合编译或解释。
在实践中,编译器语言和解释器语言之间的区别有时会模糊不清,就像编译器和解释器本身的区别一样,因为这两类程序的功能可能会重叠。虽然有些语言更常被编译,有些语言更常被解释,但可以为通常执行解释的语言编写编译器,反之亦然。
高级语言的创建通常考虑一种转换类型(编译或解释),但这更多的是建议而不是硬性限制。例如,BASIC 通常被称为解释性语言,而 C 是编译性语言,但就像有 C 解释器一样,BASIC 也有编译器。
解释器和编译器之间的主要区别在于时机和优化。这两类程序都尝试将源代码转换为可运行且可优化的目标代码。
根据操作环境的不同,考虑到硬件能力、内存和存储能力,已编译或已解释的代码可能更适合高效运行。基于任何特定程序、应用程序和硬件的限制,编译、解释或两者的结合运用都能产生最佳结果。
因此,解释不能完全代替编译,但它可以通过一个逐步转换的过程,将编译职责移动到后台。编译器采用提前 (AOT) 转换策略,在创建可执行文件之前将源代码完全转换为目标代码。
另外,解释器可以根据应用程序的需求直接运行代码,或使用字节码作为中介以输出虚拟机可执行源代码。借此,解释器或许能提升速度或灵活性,但在执行堆栈的最终阶段仍需提供可直接执行的机器指令集。
在某些情况下,当轻量级效率为优先事项时,特殊解释器由于执行即时 (JIT) 转换的能力而比编译器更可取。JIT 这种策略是将源代码片段编译成目标代码并放入内存缓冲区,以便立即执行。JIT 解释按需编译代码,将传统编译器的一次性编译效率与重复执行代码的灵活性相结合(通常比标准字节码解释器更快)。
然而,随着 JIT 编译的现代趋势的兴起以及依赖于情境的字节码解释的出现,许多编译器被设计为同时提供编译和解释功能。这种重叠进一步模糊了这两个类别之间的界限。
IBM Cloud Infrastructure Center 是一款兼容 OpenStack 的软件平台,用于管理 IBM zSystems 和 IBM LinuxONE 上的私有云基础架构。
发现专为企业混合云和 AI 策略设计的服务器、存储器和软件。
查找适合企业的业务需求的云基础设施解决方案,并按需扩展资源。