1.2 高级语言的分类
高级语言的分类方法很多,一般可以按以下几种方法进行分类。
• 按用途分类:将Java、C#和PHP归为网站后端语言;将HTML、JavaScript归为网页浏览器语言;将Fortran、MATLAB归为计算型语言;而Python是一种多功能语言,可以用于网络数据爬取、AI、VR等多个领域。
• 按强弱类型分类:强弱类型是根据语言的特性来区分的,下面解释强类型语言和弱类型语言的区别。
说明 什么是强类型语言?什么是弱类型语言?
例如,使用整数,可以用Java做如下声明:
可以看出,在Java中变量需要声明类型,并且不能赋予其他类型的值,这样的语言被称为强类型语言。弱类型语言则不是这样的,下面以Python为例进行说明:
需要注意的是,在Python中单行注释是以“#”开头的,可以看到,使用Python变量不需要声明类型,将多种不同的类型赋值给变量,这样的语言被称为弱类型语言。
一般来说,强类型语言比较规范,学习成本比较高,运行性能佳,适合大项目。而弱类型语言相对来说没有那么规范,书写比较随意,学习成本低,但是性能一般不佳,适合开发那些不追求性能的项目。
• 按面向过程和面向对象进行分类:面向过程(Procedure Oriented)是一种以过程为中心的编程思想,主要以解决问题为中心,如C语言就是面向过程的语言。在面向过程的语言的发展过程中存在许多问题,如管理混乱、大量代码冗余、可重用性差等。为了解决这些问题,后来又发展出了面向对象的语言,如Java和Python都是面向对象的语言,而C语言为了解决面向过程产生的问题,也发展出了C++语言,C++语言既兼容面向过程又兼容面向对象。面向对象的编程在Python中并不流行,所以本书不再赘述这方面的内容。
当然,高级语言还有很多分类方法,只是在编程中这些分类的大部分并不需要我们了解。与编程相关度最高的分类应该是编译型语言、解释型语言和混合型语言。这种分类方法主要与语言运行机制有关,因为计算机底层只认识二进制数,所以高级语言的代码需要翻译为二进制指令才能被计算机执行。下面针对这个分类方法进行探讨,并学习Python的运行原理。
1.2.1 编译型语言
高级语言并不是计算机能够认知的指令,所以必须将高级语言转换为计算机可以认知和执行的二进制指令,这个过程被称为编译。这种需要事先编译为二进制指令的语言被称为编译型语言,而最典型的就是C/C++。编译型语言的运行原理如图1-3所示。
图1-3中的编译器是高级语言开发商提供的,而开发者只要开发好高级语言源文件,通过编译器就可以将源文件编译为一个二进制可执行文件,这样就可以得到一个指令集,然后计算机就可以识别并运行该指令。
图1-3 编译型语言的运行原理
这个机制很快就出现了许多问题,很多时候计算机和操作系统不是相同的,而直接将其变为计算机可执行的二进制可执行文件会被某种计算机或操作系统所约束,不具备可移植性。例如,在Windows操作系统中可执行的文件是exe文件,但是它不能在UNIX操作系统中运行,所以这也大大约束了编译型语言的使用范围。编译型语言的优势是编译了二进制可执行文件,可以以较快的速度运行。
1.2.2 解释型语言
编译型语言无法在多个平台或计算机中进行移植,为了解决这个问题,一些工程师开发了解释型语言。例如,浏览器有IE浏览器、Chrome浏览器、Firefox浏览器等,它们使用不同的内核,但是都能够准确地展示超文本标记语言(Hypertext Markup Language,HTML)和运行JavaScript脚本。HTML和JavaScript脚本都没有编译为二进制可执行文件,那么计算机是如何运行的呢?解释型语言的运行原理如图1-4所示。
图1-4 解释型语言的运行原理
本书所要讲解的Python属于解释型语言。这里的高级语言源文件不需要使用编译器转换为二进制可执行文件,而是可以通过启用解释器直接运行高级语言源文件,这里的解释器的作用是将高级语言源文件解释为计算机可以识别的二进制指令,这样计算机就可以运行相应的代码。解释器是高级语言开发商提供的。不同的计算机或平台可以有不同的解释器,都由对应的高级语言开发商提供,而它们都能解释高级语言源文件,所以解释型语言可以在不同的计算机或平台之间运行。显然,解释型语言的可移植性更好,但是由于需要先将高级语言源文件通过解释器解释为二进制指令,因此程序执行相对缓慢。
1.2.3 混合型语言
编译型语言运行速度快,但可移植性差;解释型语言可移植性好,但运行速度慢。显然,它们都各具优点和缺点,而混合型语言是一种折中的方案,既可以保证程序的可移植性,也可以最大限度地保证运行速度,Java就采用了这种方式。混合型语言的运行原理如图1-5所示。
图1-5 混合型语言的运行原理
高级语言源文件首先通过编译器转换为中间文件,这里的中间文件是一种接近二进制的文件,然后解释器将这个中间文件解释为二进制可执行的指令,让计算机运行。在这个过程中会生成一个中间文件,这个文件接近二进制,但不是二进制,这样会降低解释器解释运行的复杂度,从而提高运行的速率,而这个中间文件可以在不同的计算机或平台的解释器中运行,这样程序就具备了可移植性。显然,混合型语言在可移植性和性能之间进行了折中。
注意
严格来说,上述表达并不严谨。有时候有些企业已经确定程序在固定的计算机或平台上运行,而有些高级语言开发商也提供了具体的编译器,可以将高级语言源文件或中间文件直接转变为具体计算机或平台可执行的二进制文件,这样能够大大地提高程序的性能,只是会失去平台之间的可移植性。Java和Python都可以这样做。