计算机简史(语言篇)
1. 第一天,计算机诞生了
计算机刚诞生的那会儿,是没有C#、C++、C等高级语言的,甚至没有汇编,CPU所唯一能够理解的就是一连串的二进制流,类似如下:
10010100010100101
10011001101101011
这就是最原始的"程序",其中1表示高电平(或者其他类似的东西),0表示低电平(或者其他类似的东西),CPU能读懂它,并相应的执行一些最原始、最基本如“进位”的操作,至于CPU是如何实现这种操作的,那属于电气工程师的范围,我们的程序员之旅,就以此做为出发点。
直到现在,CPU所能够唯一理解的仍是一连串的二进制流。
至于为什么,那已经不属于软件的范围。
2. 第二天,程序员说,二进制太麻烦了,于是世界上便有了汇编
随着光阴的流逝,越来越多的人参与了为计算机编写运行逻辑的工作(编程),越来越多的人觉得记住那些生涩的0和1是一项令人纠结的工作,于是···这个世界上便有了汇编语言。
基本上,汇编语言命令与二进制是一一对应的,他们联系十分紧密。
例如函数调用的 call 指令,对应着二进制的 01010110100 (这个数字是我乱写的,只为举例)。
这个时候,编译器也第一次出现了。
何谓编译器? 那时编译器就是 把 汇编指令转换为对应二进制流的小工具。
值得提出的是,汇编语言,是不能夸平台的,不能在不同架构的CPU上运行。
CPU的架构? 就是不同的CPU能够识别的二进制流,一般的,不同架构的CPU能够识别的二进制流是不一样的。
3. 第三天,程序员说,我们要跨平台,于是高级语言出现了
汇编对于二进制的流好处是,把令人崩溃的0和1转换成了简单好记的英文字符。
汇编有一个最大的缺陷,就是无法跨越平台,因为通常汇编命令与二进制的流有紧密的对应关系。
很可能在A CPU 上进位的指令是 000000001 (数字是乱写的)。
而在B CPU上进位的指令是 111111111(数字也是乱写的)。
那么为A CPU编写的汇编程序,无法在B上运行,即使有源代码也不行,因为汇编与二进制的联系太过紧密,给人灵活的空间太少。
于是高级语言便诞生了,其中影响最大的莫过于C。
高级语言最大的贡献,莫过于抽象了完成任务的方式。
在以前,用汇编语言,我们的思维方式是 用XXX指令把XXX数值放在地址为XXX的内存上。
现在在高级语言中,我们的思维方式是声明一个变量,然后给它赋值。
高级语言的工作方式,更像是一个简明、高效的指导手册,它告诉你该如何去做,只要你达到目的就行,无论你是如何实现的。
注意:直到现在,CPU所唯一能理解只有二进制的流,也就是说CPU并不理解所谓的高级语言,也不能运行那些高级语言。
那高级语言是如何使CPU运作起来的呢? 很简单,把它转换成二进制的流。
前面说过,高级语言就像是一本指导手册,告诉你该如何去做,却不管你是如何实现,而使用这本指导手册的就是编译器,正是从这个时期开始,编译器变得越来越重要,越来越,嗯~ 变态~
高级语言说定义一个变量,然后给它赋值 –> 这个语意是与机器无关的。
编译器听从它的指示,如果是要为A CPU 产生程序,它就用A所能识别的汇编指令编写指令。
使用 XXX 指令把XXXX赋值给XXXX地址上的内存 –> 这个语意是与机器有关的。
如果是要为B CPU产生程序,它就用B所能识别的汇编指令编写指令。
使用 XXX指令把XXXX赋值给XXXX地址上的内存 –> 这个语意是与机器有关的。
注意:由于汇编与二进制的流的联系是如此的紧密,所以便把它们当成是同一个对象,下文出现的也是如此。
第3.1天 C只是高级语言之一
对于许多程序员而言,从一开始进入这个领域,都是与C家族结缘,甚至一辈子,都在使用C家族的语言,这没什么大不了,C语言足够优秀,但有时,这也会阻碍我们看世界的眼光。
高级语言唯一的任务就是,提供一个唯一的、无歧义的、足够清晰的语意让编译器去理解,去使用汇编代码实现那个语意。
何谓“唯一的、无歧义的、足够清晰的语意?”
判断的标准,随着技术的进步而不同。
在当前的技术条件下(耶稣历2010年,共和国历61年)。
“定义一个int类型的变量,并把它赋值为1",这是一个唯一、无歧义、足够清晰的语意。
“给我编译一个论坛抢SF的机器人吧~”,这不是一个唯一、无歧义、足够清晰的语意。
不要被C的语意表述方法所局限,我曾有幸见识过一些COBOL语言的代码,当时给我的感觉,就像是触电… …
同样在第三天发生的事情。
第三天,一切都变得前所未有的好起来,一切又都变得前所未有的糟糕起来。
编程的效率已经大大提高了,越来越多的大型项目却陷入了泥潭。
库,框架,等概念,开始萌芽......
程序员们,陷入了思考......
程序员说,我们需要一个更聪明的编译器
于是这个世界上,便有了能替我们做更多的编译器......
面对对象的思想开始出现,并迅速的成为潮流,一大推面对对象的编程语言开始出现......
其实,这一切的一切,只不过是编译器的一个把戏,具体的实现,可以参看本人的另一篇博文。
有必要的提示:
很多时候,真相需要时间才能够被看清,当我们回顾历史的时候,经常一眼就看穿前人所犯下的错误,这并不是因为我们比那些先驱者更明智,而是因为我们经过了时间的积淀,一切浮华、虚假、谎言都是经不起时间的考验的。
同样的,生活在我们这个时代的人,也很容易被这个时代的一些东西所困惑。
面对对象只是开发软件的一个方法之一,尽管它是多么的优秀,多么的高效,但它不是神,只是可选的方案之一,任何多余的崇拜或鄙夷,都会使得你心生抵触,错过一个又一个看清真相的机会。
4. 第四天的成功者之一 C++
完全兼容C是C++的成功原因之一。
不知是C++兼容C的原因,还是C++本身的原因。
C++是一种给人无限可能的语言。
同时,也是一门让人看清真相的语言。
尽管,有时候··它的语法很让人纠结,但还是有必要去了解一下。
5. 第五天 不完美的补偿
还记得Java那句激动人心的口号吗?
“一次编译,处处运行”
这个口号曾经令多少人兴奋到夜不能寐,即使所谓的“一次编译,处处运行”已经变成了现在的"一次编译,处处调试",但我想很多人依然记得第一次接触Java时的那种感叹,虽然我没有那个亲身的经历(我是一个C#er :-) ),但我能明白那种感觉。
其实,这只是对当初犯错的一个补偿。
据说Java的运行,就是在操作系统上加一层虚拟机,抽象掉操作系统的细节。
我们犯了一个错,在操作系统兴起的时候,没有定义统一的、抽象的操作系统功能接口,如果当初那么做了,事情会简单许多许多!
如今不同操作系统之间的隔阂,已经成为割裂程序界的一道巨大伤疤。
聪明的程序员,试图弥补这些,于是便出现了Java,出现了虚拟机,并在这条路上,越走越远。
不去谈论java与C#之间的优劣,是一个明智的选择。
而且我完全不懂Java,也没有那个资格去谈论。
本博的主要目的,就是谈论.NET在第四天所做的事情,于是就不在此多说。
唯一要说明的是.NET不只是一个虚拟机~,它还有更多,更让人惊讶的特性。
最后,程序员不是上帝。
若要崇拜,迷信某样东西,那它必须足够强大,足够神秘,完全超过人类的认知范围。
很显然,程序员不是上帝,他很普通,平凡,甚至许多时候很自负。
因此,我们并不需要去迷信,去崇拜程序员创造出的世界。
试图去了解它,不要心怀畏惧。
一切都会呈现在你面前。
only_lonely 原创 转载请注明出处