11. 计算机语言是如何工作的?

我们已经讨论过 程序是如何运行的。每个程序最终都必须作为字节流执行,这些字节流是你计算机机器语言中的指令。但是人类不太擅长处理机器语言;这样做甚至在黑客中也变成了一种罕见的、神秘的艺术。

如今,几乎所有的 Unix 代码,除了内核中少量直接的硬件接口支持外,都是用高级语言编写的。(术语“高级”是历史遗留物,旨在将这些语言与“低级”汇编语言区分开来,后者基本上是机器代码的薄封装。)

高级语言有几种不同的类型。为了讨论这些,你会发现记住程序的源代码(人类创建的可编辑版本)必须经过某种翻译才能变成机器可以实际运行的机器代码,这将很有用。

11.1. 编译型语言

最常见的语言类型是编译型语言。编译型语言通过一个名为(顾名思义)编译器的特殊程序被翻译成可运行的二进制机器代码文件。一旦生成二进制文件,你就可以直接运行它,而无需再次查看源代码。(大多数软件都是以你看不见的源代码编译成的二进制文件形式交付的。)

编译型语言往往具有出色的性能,并且可以最完整地访问操作系统,但也难以编程。

C 语言,Unix 本身就是用它编写的,是这些语言中最重要的(及其变体 C++)。FORTRAN 是另一种编译型语言,仍然在工程师和科学家中使用,但年代更久远,也更原始。在 Unix 世界中,没有其他编译型语言被主流使用。在 Unix 世界之外,COBOL 广泛用于金融和商业软件。

过去有很多其他编译型语言,但它们中的大多数要么已经消亡,要么严格来说是研究工具。如果你是一位使用编译型语言的 Unix 新开发人员,那么你极有可能使用 C 或 C++。

11.2. 解释型语言

解释型语言依赖于一个解释器程序,该程序读取源代码并将其动态翻译成计算和系统调用。每次执行代码时,都必须重新解释源代码(并且解释器必须存在)。

解释型语言往往比编译型语言慢,并且通常对底层操作系统和硬件的访问权限有限。另一方面,它们往往比编译型语言更易于编程,并且对编码错误更宽容。

许多 Unix 实用程序,包括 shell 和 bc(1) 以及 sed(1) 和 awk(1),实际上都是小型解释型语言。BASIC 通常是解释型的。Tcl 也是如此。从历史上看,最重要的解释型语言是 LISP(相对于其大多数后继者来说是一个重大改进)。今天,Unix shell 和 Emacs 编辑器内部的 Lisp 可能是最重要的纯解释型语言。

11.3. P 代码语言

自 1990 年以来,一种结合了编译和解释的混合语言变得越来越重要。P 代码语言类似于编译型语言,因为源代码被翻译成紧凑的二进制形式,这就是你实际执行的内容,但这种形式不是机器代码。相反,它是伪代码(或 p 代码),它通常比真正的机器语言简单得多,但也更强大。当你运行程序时,你解释 p 代码。

P 代码的运行速度几乎可以与编译后的二进制文件一样快(p 代码解释器可以做得非常简单、小巧且快速)。但是 p 代码语言可以保留一个好的解释器的灵活性和强大功能。

重要的 P 代码语言包括 Python、Perl 和 Java。