[程序设计语言]-01:引言

1.机器语言>汇编语言>高级语言

语言是人与人的一种交流工具,就比如我现在用汉语来写这篇博文来交流探讨技术问题;程序设计语言也是如此,只是交流对象不是人而是机器。我可以用汉语来写博文,也可以用英语来写(假如我英语熟练);我可以用PHP来写一个网站,也可以用ASP.NET来写。这就说明语言的本质就是一种交流工具,而我选择哪种语言来交流并不会影响我要的结果。然而在实际中到底要选用那个语言确要根据具体情况而定,这是个成本问题,比如我如果今天脑子抽筋要用日语,那我写着也累(关键是也不会)、读者或许也会骂娘了。

早期的计算机是一台超级庞然大物,能耗抵得上一家小型工厂,而计算能力确不如今天的一台手持计算器。也就是当时人力成本要远远低于这台机器的机器成本,也就决定了当时是以机器为中心,而不是人。所以人们用计算机能直接理解的机器语言来编写程序。这里有一个计算两个整数的最大公约数的栗子(MIPS R4000处理器的机器语言),16进制形式如下:

1 2dbdffd0 afbf0014 oc1002a8 00000000 0c1002a8 afa2001c 8fa4001c
2 00401825 10820008 0064082a 10200003 00000000 10000002 00832023
3 00641823 1483fffa 0064082a 0c1002b2 00000000 8fbf0014 27bd0020
4 03e00008 00001025

这些机器语言对人的阅读和理解相当的不友好。当程序越来越复杂,人们迫切需要一种简单不易出错的记法形式,于是人们创造了汇编语言,用简短的词语来助记机器操作。用MIPS R4000处理器的汇编语言重写上面的栗子如下:

 1    addiu  sp,sp-32
 2    sw     ra,20(sp)
 3    jal    getint
 4    nop
 5    jal    getint
 6    sw     v0,28(sp)
 7    lw     a0,28(sp)
 8    move   v1,v0
 9    beq    a0,v0,D
10    slt    at,v1,a0
11 A: beq    at,zero,B
12    nop    
13    b      C
14    subu   a0,a0,v1
15 B: subu   v1,v1,a0
16 C: bne    a0,v1,A
17    slt    at,v1,a0
18 D: jal    putint
19    nop
20    lw     ra,20(sp)
21    addiu  sp,sp,32
22    jr     ra
23    move   v0,zer

对于这个栗子,阅读和理解上明显要比机器语言要容易得多。然而这种编码形式计算机是不识别的,需要一种叫做“汇编器”的程序来翻译成对应的机器的机器语言才能执行。这种一个汇编指令对应一个机器之路的关系还是显而易见的,对于不同的计算机,则还需不同的汇编语言来编写;这个时代的程序设计仍然是以机器为中心,程序员也许要以机器的思维来解决问题。

就如同机器语言到汇编语言的过渡一样,程序越来越复杂、各种类型的计算机越来越多,为每一种机器都编写程序也越来越困难、人力成本也越来越大。

根据计算机科学领域惯用的抽象原则,人们需要一个中间层来隔离某一个计算操作对具体机器的具体操作指令的这种对应关系,也就是这个中间层需要独立于具体的机器操作。随后人们就创造出了高级程序设计语言来做这么一个中间层,由于剥离了计算操作到具体机器操作的对应关系,但是机器具体执行的依然还是机器操作,那么也就需要一个更“高级的翻译器”来做这项翻译工作,这个高级的翻译器就是现在所说的编译器。

由于这种翻译工作是由机器来完成的,在编译器出现的早期时候,人们总是能够写出比高级语言代码更高效的相应的汇编语言(毕竟早期的时候计算机的计算能力还一种奢侈的资源)。但是随着程序进一步的扩大、硬件性能的提升、编译器的优化、程序的维护成本等等变化,这种性能差异和人力成本相比慢慢也就显得微不足道了。现在想一想,当初c++面世的时候、基于虚拟机技术的java出现时也是这么一种情况。

自从高级程序设计语言出现以后,程序设计慢慢开始从以机器为中心向以人为中心转变。

2.编译和解释

按照抽象的观点来看,高级语言的编译和执行大致是如下的样子:

编译器把源程序翻译成目标程序(典型的是机器语言程序)后就隐退了,后面的程序的运行中就不在需要编译器的存在了。

解释器是另外一种实现高级语言的方式:

和编译器不同的是,解释器一直全程守候。解释器本身相当于一个“虚拟机”,它的“机器语言”就是源程序的高级语言。和编译器相比,解释器可以有更大的灵活性。它可以轻易地做到在程序运行初期来生成某一块新的代码,然后再后续的某一个时间去执行它;以及把一些决策推迟到运行时再去做决定。和解释器相对应,编译型的语言通常可以带来较好的性能,它可以在编译时期就把一些决策确定下来,比如一些内存布局。

虽然两者的概念很清晰,也有较大的差异性,然而现实中有些语言是“混合型”的,流程大致如下:

如果初期阶段的翻译器比较简单,则我们把它称为解释型语言;如果翻译阶段复杂,则成为编译型语言。然而简单和复杂本身是个形容词,而不能可量化。完全有可能出现一个复杂的翻译器负责中间语言程序的生成,一个复杂的虚拟机(解释器)来执行中间语言,JAVA、.NET也正是这种实现方式。

2.1连接器和预处理器

我们所用的高级语言所写的程序通常还需要一个库(包含一些IO、网络等等的操作),在编译的时候就需要把我们写的源程序和库程序链接到一起来生成目标代码,比如我要读写文件,则需要链接IO相关的库程序。通常情况下目标代码为汇编语言而不是机器语言,这种方式更有利于调试程序,也便于阅读,更能把编译器和机器语言文件格式的变化隔离开来。预处理器可以提供一种条件编译的功能,比如C#中编译条件#if DEBUG这些东西,再如C、C++中的宏机制也是属于预编译的范涛。

3.程序语言的设计实现以及分类

现实中语言的设计和实现总是有不可调和的矛盾,从设计角度来看总是希望一个语言能有更强大的表达能力,然而却总是受到语言的实现制约。这根本原因大概也许是以人为中心和以机器为中心的矛盾吧,因为你的语言的执行最终还是离不开机器的执行,所以语言设计者也是不得不在这两者中间寻求平衡。

依据现有的计算模型(运算产生结果或运算影响结果),大致分为两大类(当然这些所谓的分类也是从不同角度得来的,如果你站在另外的角度看,或许就是另外一番景象了)说明式语言和命令式语言。从某种的角度看,说明式语言明显要更“高级”,因为它更贴近使用者-程序员,而更远离实现者-语言设计者。然而现在的语言还是命令式占据着统治地位,主要是因为实现的难度、性能的要求等原因制约着说明式语言的发展。上层是抽象的高级语言,下层是实现的细节,抽象层级越高,实现的难度则越大,因为你要隔离隐藏的细节越复杂。

函数式语言是说明式语言中的一个,近年它的热度也是急剧上升来着;我们熟知的C、C++、JAVA,C#等都是属于冯诺依曼体系的范涛,当然也是命令式语言的子集。和函数式语言中的把函数和数值作为语言的一等公民(可以赋值为给变量、作为参数传递、作为返回值处理)不一样的是,冯诺依曼语言的中的基本操作是赋值语句,它们通过“副作用”去影响后续的计算结果。

脚本语言比如JS,它们一般都是拥有强大灵活度的解释性语言,一般充当着“粘结剂”的角色。等等还有诸多的语言分类,就不在此赘述了。

总结

本篇介绍了语言的从机器语言到汇编再到高级语言的演进过程以及其发展的驱动力;以及高级语言的两种实现方式“解释”和“编译”的差异;以及按照语言的计算模型进行的语言分类。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏牛客网

腾讯阿里网易游戏华为科大讯飞面经

47890
来自专栏小樱的经验随笔

设计模式六大原则(3):依赖倒置原则

定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。 问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过...

29480
来自专栏Crossin的编程教室

【Python 第49课】 面向对象(3)

面向对象是比较复杂的概念,初学很难理解。我曾经对人夸张地说,面向对象是颠覆你编程三观的东西,得花上不少时间才能搞清楚。我自己当年初学Java的时候,也是折腾了很...

26840
来自专栏python+iOS学习交流

python入门 2018最新最全学习资料免费获取啦

是否非常想学好 Python,一方面被琐事纠缠,一直没能动手,另一方面,担心学习成本太高,心里默默敲着退堂鼓?

13320
来自专栏杨建荣的学习笔记

Python实现的快速排序

今天看了下《算法新解》这本书,很薄的一本书,最开始吸引我的有两点,一个是里面的大量的图,内容相对来说比较清新,第二个是里面的代码是基于Python实现。尽管算法...

39870
来自专栏程序人生 阅读快乐

JavaScript语言精粹(修订版)

JavaScript曾是“世界上最被误解的语言”,因为它担负太多的特性,包括糟糕的交互和失败的设计,但随着Ajax 的到来,JavaScript“从最受误解的编...

7810
来自专栏java一日一条

为什么程序员总是写糟糕的代码?这3个原因

我一下子想到的最明显的原因是,有好的程序员,也有不那么好的程序员,有的人技术水平高,有的人水平却低,有人对这门技艺感兴趣,但也有的人却不愿意在工作之外学习其他。

7930
来自专栏奇点大数据

如何零基础入门Python编程?

Python目前已经成为最受欢迎的编程语言之一,吸引了一大批粉丝,但是很多人在要跨入的时候犹豫了,原因竟然是觉得零基础学习Python太难了,真的是这样吗?零基...

21040
来自专栏大数据钻研

为什么程序员总是写糟糕的代码?这3个原因

我最近一直在想我们作为一个行业为什么总是产出糟糕代码的原因。 1.明显原因…… 我一下子想到的最明显的原因是,有好的程序员,也有不那么好的程序员,有的人技术水平...

33980
来自专栏极限编程

解析简单设计原则

在 我的简单设计价值观 一文中,我分享了我在实践中形成对简单设计的理解。而提到价值观,平时跟同事讨论某个技术实践的时候,一旦触碰到价值观,我就会很谨慎,因为在两...

14060

扫码关注云+社区

领取腾讯云代金券