现代的电脑发展非常迅速,并且变得越来越快。然而在这种快速的变化中,却有着标志性的约束条件。电脑仅仅能懂一些最基础的指令,并且需要外界明确地告诉它怎么做。编程语言就是这样系列基础指令的集合。真正执行指令的部分是计算机的硬件部分。
机器语言:
机器的CPU并不能识别C++。CPU能够执行的是严格受限的机器语言。虽然改语言有点超出该教程的范畴,但是这里值得注意两件事情。首先每一条机器指令只用使用二进制,即0或者1.这些二进制数字常常被称作比特(bit for binary digit)。举个例子来说,对于一个MIPS架构的指令集来说,一般都有32比特的数据。其他的架构,比如X86,指令集的长度是可变的。
X86机器指令集的例子:10110000 01100001。
其次,每个特殊的指令集被CPU识别为一个特殊的操作,比如说比较两个数值,以及把某个数值放到一个内存中。不同的指令集在不同的系统中可能表示的意思不同,也就是说在奔腾4上可以正常执行的指令,在其他系列的机器上不一定能运行成功。退回到电脑刚刚发明的时代,人们只能用这些机器语言编程,这个非常困难。
汇编语言:
因为面向机器语言编程非常困难,所以发明了汇编语言。在汇编语言里,每一个特殊的操作都有一个简短的短语,而不是一串二进制数字。这就让编程变得更加简单。然而,机器是不能识别这些汇编语言的。因此,必须使用编译器将汇编语言转换成机器语言。汇编语言是一种执行非常快的语言,当今如果对程序速度有比较高的限制的话,依然会使用汇编语言。然而汇编语言如此快的原因是因为汇编程序是根据CPU定做的。在一个CPU上写的汇编语言在另外一个CPU上不一定执行成功。并且汇编语言依然需要大量的指令集来编程,非常不人性化。
汇编语言替换上面机器语言的例子:mov al, 061h
高级语言:
为了解决上面提到的系列问题,高级语言被发明了。C,C++,JAVA,PASCAL,JAVASCRIPT等都是高级语言。高级语言的编写可以不依赖于具体的运行环境。在CPU执行程序之前,高级语言必须翻译成机器语言让CPU识别。翻译由两步构成:编译和解释。
编译的过程是读取一段代码,并且翻译成CPU可直接识别的标准可执行程序。一旦你的代码编译成了可执行程序,你就不需要编译器来执行改程序了。尽管看起来高级语言的效率比汇编语言差一些,但是现在的一些编译器在语言转换方面是非常优秀的。有时候他们甚至要比一些汇编语言都高效。
下图是一个编译过程简单的例子:
解释器是一种程序,无需转换成机器语言,直接执行的程序。解释器往往效率比较低,因为每次跑程序都需要使用解释器。这意味着解释器在程序跑的过程中一直运行。
下图是一个解释器的例子:
任何一种语言都可以编译或者解释,然而传统的语言如C,C++都是编译形的语言;然而带有script的语言如javascript,perl是解释型语言。JAVA则是两种都用了。
高级编程语言有几个可取的特性。
首先,高级语言更容易读和写。
如下是上面汇编语言和机器语言的例子:a = 97;
其次,高级语言往往需要更少的指令来编写程序。如C++ 中的a=b*3+5;如果放到汇编语言里,那么至少得写5到6行。
再次,你没有必要关注一些细节,比如讲某个值放到CPU的寄存器里。编译器或者解释器帮你处理了这些细节。
最后,高级语言可以到处移植,这个后续我们会继续讨论。
然而可移植性也是有特例的,比如微软的平台开发软件往往会用到系统封装好的一些函数库。这些集成好的库往往可以很方便地开发代码,但是会损失掉可移植性。本教程中会明确说明哪一些是特殊平台所特有的东西。