Python语言基础
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1 计算机程序语言层级结构

从自然语言这方面来讲,人类之间交流用的语言种类是很多的,如常用的汉语、英语、法语、德语、俄语、日语等,这些语言使用的文字有些是象形文字,有些是拼音文字,有些则是两者的混用。类似地,如图1-1所示,用来对计算机发布指令的语言也有很多种类,我们可以称之为计算机程序语言(简称“程序语言”),大致可以将程序语言分为三类:一是机器语言,二是汇编语言,三是高级语言。

图1-1 计算机程序语言层级结构

最早的程序语言是机器语言。在这种语言中,计算机的每项指令都是用一串二进制数字表示的。虽然真实的情况可能比较复杂,但其原理却是比较简单和直观的。为了方便理解,我们不妨忽略大部分的细节,在此处做一种最简单的假设。例如,我自己设计了一台计算机,这台计算机可以进行加法和减法的简单运算,而我可以规定,做加法的指令为“00000001”,做减法的指令则可以为“00000010”。有些同学可能会很好奇,为什么机器码的形式这么奇怪,我们平时在操作计算机的时候,点点鼠标、敲敲键盘就可以让计算机帮我们做很多事情,好像从来都没试过对着计算机念这样一串串数字。这是因为计算机工程师为了让大家都能使用计算机,把这些细节隐藏起来了。这些聪明的工程师专门制作了能够把我们单击鼠标、敲击键盘的动作转换成0/1数字序列的翻译工具,这个翻译的过程极其迅速和隐蔽,以至于我们根本察觉不到它的存在。

事实上,计算机真正能够识别的语言只有机器语言,使用其他任何形式对计算机发出的指令,最终都必须转化为机器语言才能够被计算机识别和执行。要理解这一点就需要对计算机的结构有一个大致的了解。现代电子计算机的核心部件—中央处理器(CPU)其实就是一块电路板,它的作用就是接收数据和指令,根据指令对数据进行相应的计算,最后将计算结果返回。如果只考虑最简单的情况,电路板一条电路的可能状态就只有通电和断电两种,而我们所要做的就是用通电/断电的电路状态组合来表示数据及指令,启动对应的电路状态操作,操作的结果就是计算机所得出的新数据。

那么,要怎样才能做到这一点呢?此处以最简单的自然数加法来进行说明。以“2+3=5”为例,这个式子用我们日常生活中最常见的十进制表示待计算的两个数“2”和“3”,用“+”表示加法,用“5”表示所得的结果。根据我们的计算习惯,可以通过对电路状态的操作实现十进制数学计算。

如图1-2所示,我们将9个小灯泡排成一行,用2个这样的排列来表示2个加数,灯泡亮起的个数分别表示希望相加的数据2和3。我们用另一行小灯泡表示计算符,此处用1个小灯泡亮起表示加法(其指令编号为00000001),最后可以得到一组有5个小灯泡亮起的排列,表示前面两个数相加的结果为“5”。虽然这个模型看起来很简陋,但CPU确实就是用这种朴素的思想搭建起来的。可能你听说过ENIAC这台最早的电子计算机,印象中它又大又复杂,但它的设计思路同这里所讲的内容并无二致。

当时有一位很了不起的计算机科学家—冯·诺依曼,他敏锐地觉察到,用电路状态表示十进制的数字在工程上过于复杂,于是他建议直接使用电路状态表示二进制数字,这样做的好处是能够使电路状态和数字的映射关系变得直观和清晰,从而大大降低电路设计的复杂度。如图1-3所示,若用二进制来重现刚刚的计算,就可以得到更为简洁的电路状态。

图1-2 通过对电路状态的操作实现十进制数学计算

图1-3 通过对电路状态的操作实现二进制数学计算

通过比较两种电路所能表示的数字范围,我们可以大概了解它们之间的效率差异。前面一组电路含9个小灯泡,只能表示0~9的数;后面一组电路含8个小灯泡,却能表示0~28-1(0~255)的数。看,这是多么大的差距,如果后者换成9个小灯泡,则能表示0~29-1(0~511)的数了。基于这种设计的优越性,后来所有的计算机都继承了用电路状态来表示二进制数与二进制数计算符的方法。CPU最终所能接收的数据和计算指令本质上是一组电路状态,而冯·诺依曼的设计使我们能够将其和二进制数及其计算对应起来。简而言之,机器语言就是用二进制数对计算指令和数据加以编码的语言,如将加法编为00000001,将减法编为00000010,以此类推。同时,CPU只能理解用机器语言写出的语句,这是由它的电路结构决定的。

通过以上内容,我们对机器语言有了一个大致的了解,那汇编语言又是什么呢?这就要从一位传奇的女性—格蕾丝·穆雷·霍珀说起,作为一名数学家,她为美军服务,美军为了留住这位“奇才”,不断地给她提升军衔,最后升至少将。她的主要工作就是为美军做计算,面对当时的计算机,她只能不断地将要做计算的数据和算法用二进制数描述在长长的纸带上。虽然她本身是个数学家,但她还是认为用一串串二进制数来表示计算指令的方法太难记忆,于是着手设计一种更简便的替代方案。

格蕾丝发现,在电报的编码中,是用二进制数字串来表示一个个字母的,为什么不将其用于文字在计算机中的编码呢?于是她便设计了汇编语言。给每个计算符分配一个英文单词,而单词中的每个字母又可以用二进制数来表示。如此一来,可以把计算中涉及的所有的计算符用英文单词来表示,再有一台能够将单词翻译成对应的机器语言的机器就可以了。这台进行翻译的机器,就称为“编译器”或“解释器”。

虽然汇编语言在很大程度上降低了编写指令的复杂度,但它还是很复杂。有没有更简单的解决方案呢?有!那就是高级语言。高级语言的设计思路和汇编语言很像,也是利用文字来进行指令的编写。但高级语言的写法更加贴近自然语言,如使用if...then...表示条件分支。现在的软件工程师主要通过高级语言来跟计算机沟通,而Python正是高级语言的一种。类似的高级语言还有Java、C语言等。与汇编语言一样,每种高级语言都有一个自己的“编译器”或“解释器”,负责将用高级语言写成的语句(代码)翻译成机器语言。编译器和解释器的功能类似,前一种是整体翻译,后一种则是即时翻译。具体细节我们不在本书中做过多讨论,但有一点请大家牢牢记住:“所有的Python代码都要在被送到解释器中并被翻译成机器码之后,才能被CPU理解并运行。”