在“Web开发杂谈”系列的上一篇文章中,简单介绍了一下如果作为初学者,应该具有一个怎样的心态和预期去面对要学习的内容。就像我们新到一个陌生的城市,最需要的是一张地图;同样,进入一个新的技术领域,也应该尽快为自己找到一张地图,使自己有学习的方向和预期,只有这样才可能把学习进行下去。
实际上,我们在上一篇文章里,介绍的是一些很通用的做事方式,仔细想一想,其实做任何事情都是“一样一样”的ho~,无非都是要:1)掌握一定的知识和理论作为基础,2)并且要有实际动手操作的能力。前者即所谓的“认识世界”,后者即所谓的“改造世界”,然后再不断积累经验提升水平。对要做的事情,认识得越深刻,动起手来就越有把握。
不过我在上一篇文章中,把学习的过程分为了三个层次,为了避免读者的误解,这里做一些解释。尽管说,要先把基础掌握好,再去动手实践,但是并不是意味着,只顾着埋头去看那些理论,等全明白了之后再去实践。毕竟,要做的程序开发,是一个实际操作的事情,一定要两条腿走路,一边理解,一边实践,二者是相辅相成的,这样效率也会高很多。
因此,今天就来谈谈开发中最基础的一个话题——编程语言。就像每个人要生活在世界上,就离不开语言一样;要做软件开发工作,也是绝对离不开“编程语言”的,你的一切“改造世界”的行动,都是通过使用“编程语言”来编写程序实现的。
编程语言的基本原理
当今的计算机都是按照“冯.诺依曼”体系设计的,其运行的基本原理,可以简单概括为“程序存储、集中控制”这8个字,最核心的两个部分就是控制器和存储器。无论存储器是什么形态,几十年前的继电器,还是现在的DDR3内存条,程序都必须要装载到存储器中,然后控制器在时钟脉冲信号的控制下,有节奏地依次取出程序代码,执行相应的指令,周而复始。
而在存储器中存放的是两种信息:1)数据,即操作对象;2)程序,即操作指令。
因此无论你使用什么编成语言,你都是在做着同样的两件事:
1)告诉CPU你的数据在哪里;
2)告诉CPU你希望如何处理这些数据。
比如假设某一种计算机,有这样的一条指令: ADD [1000],2000 ,它的意思就是取出存储器中第1000号存储单元中的数值,让后把它增加2000,再存回第1000号存储单元。而每种计算机都有一套完整的指令集,比如Intel的 X86 CPU 和 IBM的 Power-PC CPU就具有完全不同的指令集,因此他们是不兼容的,而我们日常使用的Intel的 CPU和AMD的CPU的指令集则是兼容的。
而我们通常开发软件编写程序,是不会写“ ADD [1000],2000 ”这样的代码的(这种代码称为“汇编语言”代码),而比如说,我们如果用C语言,则会写出这样的一条语句:” X = X+2000 ; ”
,其含义同样实现了在X这个存储单元的数值增加2000这个目的,而写起来就方便多了,用变量名称代替了存储器的编号,我们也不需要知道X这个变量到底在第几号存储单元,只要知道有这么一个位置就可以了。
而C语言代码是如何变成机器可以理解的代码的呢?这就需要中间有个翻译的机制,分为两种:1)编译程序,2)解释程序。
前者把高级语言代码彻底翻译为机器语言代码构成的程序,然后再运行;后者在运行的时候,一边翻译,一边运行。在大学的计算机本科的高年级,都会有一门课程叫《编译原理》,专门讲解这个问题。
编程语言的来历和演变
编程语言经历了从无到有,从低级到高级的演变过程。需要注意这里的高级和低级没有好坏之分,低级表示的更接近于机器的底层硬件,高级表示更接近于要是解决的实际的问题,而不必考虑计算机底层的运行方式。
史前时期
实际上,计算机出现之前,就已经有很多数学家为计算机软件的出现打下了坚实的数学理论基础,比如著名的数学家“阿兰.图灵”和他的导师一起努力,在20世纪三、四十年代年代就创建立了“图灵机”理论,从理论上解决了计算机软件和核心——“计算复杂性”以及“算法表示”问题。前者研究“能不能计算”的问题,后者研究“如何计算”的问题
正是有了这样的数学理论作为基础,加上当时电子技术的突飞猛进,二者相结合,才产生了计算机这样一个划时代的伟大产物。
低级语言
计算机的内部处理的全都是1和0的二进制数字,表示“开”和“关”,而计算机刚刚发明出来的时候,操作人员就必须用很多真正的“开关”来操作计算机,进步一点以后,出现了“机器语言”的概念,使用例如在纸带上打孔的方式,把一些原来需要人手工拨动开关的操作序列,变成按照某种规则在纸带上的一系列孔的序列,这种打着孔的纸带可以被看作是今天的鼠标、键盘、打印机、显示器、磁盘这些东西的总和,这些东西在当年,“打孔纸带”一个人就全包了。
机器语言通常称为“第一代语言”,其后又产生了“汇编语言”,即“第二代语言”,汇编语言实际上就是机器语言,区别就是汇编语言中用一些符号代替0和1的序列,仅仅是便于记忆,此外,有少量的扩展功能,比如可以通过定义的“宏”来产生类似于“子程序”这样的逻辑概念,通过编写汇编语言程序产生机器代码,效率提高了很多,但是它依然是紧密依赖于机器的,和后来被广泛使用的高级语言是完全不同的。
高级语言
接着,历史的车轮继续开动了,所有计算工作都要转化为机器相关的代码,这个事情本身就非常复杂,因此人们就想到,能否设计出一些更接近于人类自然语言的方式,来操作计算机呢?这里要提到的两为大牛,一位叫“约翰.冯.诺依曼”,一位叫“约翰.巴科斯”。
前者“约翰.冯.诺依曼”,可以称为“计算机之父”,美籍犹太人,数学神童出身,可以说是数学和计算机科学界的“爱因斯坦+爱迪生”,40岁以前搞纯数学研究,40岁以后把纯数学应用到应用数学、量子物理、计算机科学、核武器、经济学等各个研究领域,把数学作为工具,用得是出神入化,所向披靡。如果没有这位神人,说不定大家今天还在打算盘,呵呵(甚至比这还惨,如果没有他,也许还要晚扔那两颗牛X的原子弹)。至今的计算机(除了一些研究性质的),都没有离开“冯.诺依曼”设计的结构,所有大学生学习的计算机知识,都是基于“冯.诺依曼体系”的。
后者”约翰.巴科斯”,当然也是大牛,不过从地位来讲,不能和“冯.诺依曼”相比了。他的主要贡献就是对高级编程语言的开创性工作,他认为,应该建立脱离依赖于计算机结构的程序设计语言。这里有个有流传的说法,说在1950年代,这两位“约翰”对这个问题有所争论,“诺依曼”认为不需要高级语言,而“巴科斯”认为需要高级语言。我查了查网上相关的资料,似乎没有明确的证据说明“诺依曼”认为不需要高级语言,因为“诺依曼”在1957年,年仅53岁就去世了(真是太可惜了),我没有查到他说过“不需要高级语言”这样的话,只是“巴科斯”在图灵奖获奖报告中提出了他的建立高级语言的思想而已。
总之,“约翰.巴科斯”建立了高级语言的思想,并设计出了世界上第一个真正意义上(至今广泛应用)的高级语言——Fortran语言。此后,就不断出现了各种各样,具有各自特点的高级语言了,这样,普通人即使对计算机的内部结构不是非常清楚,也同样可以进行软件开发了。
编程语言的基本构成
通常来说,一个编程语言主要包括下面三个基本组成部分:
1:类型系统 —— 定义了这种编程语言中使用的数据定义方式,也就是解决“操作什么”的问题。通常包括“静态类型”、“动态类型”等不同的类型系统。比如C、C++、C#、Delphi、Java等等都是静态类型语言,而Javascript、PHP、Python、Ruby等则是动态类型语言
2:语法规则 —— 定义了这种编程语言的流程控制方式,或者说解决“如何操作”的问题。对于过程式的语言,比如C语言,一个程序有三种流程控制结构:“顺序结构”、“分支结构”和“循环结构”。
3:标准库 —— 为了解决实际生活中的问题(专业说法叫做“领域问题-Domain Problem”),编程语言通常都会提供一些预备好的核心功能库,供程序员直接使用。比如你需要在程序中计算一个角度的正弦值,那么要通过基本的加减乘除这些基本运算,计算出来是很繁琐的,而这个功能有非常常用,因此,编程语言就会提供一些数学公式的计算函数库,这样程序员就可以方便地调用了。
说明:
1:实际上面的前两条是真正一个编程语言的核心,而标准库是可以扩充的,或者由第三方提供的。以.NET平台为例来说,在.NET平台上可以运行多种语言,比如C#、C++、Basic、甚至ironPHP、ironRuby等语言,每种语言都有自己的类型系统和语法规则,而他们共享同一的标准库,也就是.NET框架提供的大量已经开发好的程序库。
2:所谓核心就是体积比例很小,作用超大的东西。当年TruboPacal ,后来的Delphi,再后来的C# 的设计师Anders Hejlsberg曾提到,在他的团队里,做C#语言设计的人是4个人,写C#编译器的也就几个人而已,而编写.NET框架的人就有上千人了。从中我们就可以知道“核心”的含义了。
3:说到Anders Hejlsberg,这里必须要说一说,他也是个天才,应该是程序员做到头的终极榜样了。如果读者朋友,您不喜欢尔虞我诈的人际关系的争斗,而喜欢做单纯一些的技术工作,又没有名牌大学的博士学位,就以Anders为榜样吧,Anders是丹麦人,在丹麦上的大学(但是没有毕业,原因不得而知),到美国以后和伙伴一起开发出了Turbo Pascal,一举成名,后来在Borland公司不得志的情况下,被Bill Gates三顾茅庐,请到了微软。具体故事可以参考台湾技术作家李维的一本书《Borland传奇》,非常有趣。一名纯技术人员,能做到这样,基本上算是到头了。
思考题
1:本文列出了4位大牛,除了他们令人望尘莫及的天赋,你能从他们的经历中寻找到一些什么启示?
2:你能在头脑中想象出一个简单的程序在计算机中是如何运行的吗?
3:你使用哪种编程语言,你为什么选择它?
在下一篇文章中,我们将对目前流行的编程语言做一些介绍,使初学者有一个大致的了解,也可以帮助大家选择自己的学习路线。