1、主流编程语言优劣整理收集自:P57 效果()这里,我将比较一下几种主流编程语言:C ,C+ ,Java,.NET,Ruby,JavaScript。其他主流编程语言,如 Pascal,Delphi,我不太熟悉。希望熟悉的朋友能够补全对这些语言的评价。至于 Basic,它的版本差异很大,而且能力不太全面,这里也不做评价。语言特性对比表C C+ Java .NET Ruby JavaScript类型 无类型 强类型 强类型 强类型 强类型 强类型静态/动态 静态 静态 静态检验类型动态解释执行 动态 动态支持面向过程 是 是 否 否 否 是支持基于对象 否 是 否 是 是 是支持范型 否 否 是 是
2、 否 否支持模板 否 是 否 否 否 否支持面向对象 否 是 是 是 否 否可能你对于我这样的语言评价有些疑问,请首先看我的另一篇文章基于对象和面向对象编程范式辨析和主流编程语言中的应用 理清相关的概念。我对与面向对象和基于对象的定义和流行的定义不太一样。C 语言优劣考C 语言由来让我们先回顾一下历史。电脑使用 CPU 指令,通过寄存器,内存等物件执行计算。最早的编程,是直接使用代表CPU 指令的机器码编写的。直接使用二进制的数据编程,当然很容易出错。于是,人们后来发明了一种方法,就是使用英语单词作为助记符,代表各条 CPU 指令。这就是汇编语言。现在,程序员可以使用英语单词进行编程,然后使用
3、一个解释程序,把汇编指令翻译成机器语言,再交给计算机执行。1970 年,UNIX 操作系统的研制者丹尼斯里奇(Dennis Ritchie)和肯汤普逊(Ken Thompson)为了更好地编写操作系统,发明了 C 语言。C 语言比汇编语言更先进。它使用了面向过程的编程范式。同时它仍是一门十分接近汇编语言,面向机器的编程语言。适合编写操作系统和其他直接操纵硬件硬件的编程。面向过程编程范式下面是我查到的过程式设计的定义:过程式设计:1、自上而下(top-down)的设计方式:是一个自顶向下,逐步求精的过程;2、以 main 函数概括出整个应用程序需要做的事情,而 main 函数由对一系列的子函数的
4、调用组成;main 中的每一个子函数都可以被精炼成更小的函数。重复这个过程,即可完成一个过程式的设计;3、特征是以函数为中心,以函数作为划分程序的基本单位,数据往往处于从属地位。过程式设计的优点:易于掌握与理解,符合人们的思维习惯;过程式设计的缺点:1、不能适应问题比较复杂,或者需求经常变化的情况;2、数据与操作分离开,对数据与操作的修改变得很困难;3、程序架构的依赖关系不合理:main 函数依赖于子函数,子函数又依赖于更小的子函数;而子函数往往是细节的实现,这些实现是经常变化的,造成的结构就是:程序的核心逻辑依赖于外延的细节,一个细节上的小改动,会引起一系列的变动。我对于面向过程编程范式是这
5、样理解的:面向过程编程,就是使用函数代表处理的过程。这些函数使用的数据,要么是参数,要么是外部的数据。使用函数编程,这看上去很像函数式编程。但面向过程的编程范式不同于函数式编程。函数式编程的函数,一般不使用外部的数据。不维持外部的状态。这有很多优点,但也同样有了很大的局限性,不似面向过程编程这样方便。C 语言就是典型的面向过程编程语言。它通过函数抽象了过程处理。函数,就是 C 语言的接口。C 语言中,数据常常作为全局的变量保存起来。这样,使用 C 语言编程就很难保证其他代码不破坏函数依赖的数据的状态。这是 C+基于对象编程范式出现的原因。这个我们稍后再说。我们再看看 C 语言对机器指令的抽象。
6、C 语言是一门十分接近汇编语言的语言。所以有人说 C 语言既是一门高级语言(面向过程,函数) ,也是一门低级语言(面向机器,直接反映计算机的实际计算过程) 。C 语言使用原生类型,数组, Struct 等来表示数据。C 语言中,数据在内存中的表示是十分确定的。程序员可以充分控制。如,C 语言中可以使用 memcpy()直接复制内存中的数据。现在,大多数的操作系统原生函数库,都使用 C 语言作为其接口。绝大多数的语言都具备与 C 语言函数库进行互操作的能力。C 语言可以说是程序世界的世界语。C 语言的优点 1, 面向过程开发,以函数为中心。简单有效。实现了简单的接口。2, 面向机器,让用户可以完
7、全的操纵机器,效率较高。C 语言运行高效,广泛应用于各种计算领域。对于简单的任务,非常有效。 C 语言的缺点 1, 函数无法有效控制需要的数据。不能保证外部状态不变。容易出现 Bug。2, 对于机器的控制太强,也就是依赖太强。由于过于强调效率,使用 C 语言编程时,更多的需要考虑机器,而不是问题本身。由于过于关注机器,而不是问题域本身,因此抽象能力不足。容易出现各种 Bug。对于编写大型的程序,常常力不从心。C 语言的使用方法C 语言作为一种简单高效的编程语言,适用于编写简单的程序。在编程中,应该注意扬长避短,使用面向过程的编程范式,少用对机器的依赖。1, 使用函数编程时,应该尽量使用函数参数
8、传递状态,少用全局数据。因为,你无法保证全局数据不被其他代码改变。这样使用函数,叫作“纯函数 ”。类似于函数式编程的用法。而且,使用这种方式编程,由于不存在全局数据,在进行多线程开发时,还不需要考虑多线程问题。2, 使用结构化的编程方式。不要卖弄技巧。3, 函数是接口。尽量使用函数调用,而不是直接的代码。通过层层分层,分配职责,编写出短小精悍,易于维护的代码。4, 尽管 C 语言是一种面向机器的语言。但是,我们还是应该尽量少地依赖机器。多从问题域来考虑和抽象问题。如,少用内存假设等等。因为,我们会使用很多种语言,C,C+,Java,C#等语言的很多语法类似。但是实际的表现,各个语言都是不同的。
9、如果过分考虑 C 的机器特性,那么很可能会因为记错而编写出错误的代码。5, 代码,首先是给人看的。顺便给机器执行!不要处处优化代码。只应该优化性能瓶颈。因为优化的代码,常常表示很难看懂!6, 应该大量使用 Struct 组织相关的数据。在用 C 语言编程时,也应该树立类型和对象状态的概念。把 Struct 作为函数的参数传递数据。C+语言优劣考在 C 语言优劣考中曾经说过: C 语言中,数据常常作为全局的变量保存起来。这样,使用C 语言编程就很难保证其他代码不破坏函数依赖的数据的状态。这是 C+基于对象编程范式出现的原因。C+最初是作为 C 语言的扩展出现的,最初的名字就叫“带类的 C”。后来
10、,C+逐渐演化成一门独立的语言。但还是和 C 语言兼容。基于对象的编程范式基于对象的编程范式,又称“抽象数据类型” (ADT) 。面向过程的编程范式中,函数无法控制函数外的共享数据。这使面向过程的编程语言不能很好地编写大型系统。为了解决这个问题,人们发明了基于对象的编程范式。就是把数据和处理数据的函数都封装在一个类中。这样,共享的数据就不会再被外部的代码改变了!下面是我查到的定义:抽象数据类型(Abstract Type 简称 ADT)ADT 是指抽象数据的组织和与之相关的操作。可以看作是数据的逻辑结构及其在逻辑结构上定义的操作。ADT 的描述规范一个 ADT 可描述为:ADT ADT-Nam
11、eData:/数据说明数据元素之间逻辑关系的描述Operations:/操作说明Operation1:/操作 1,它通常可用 C 或 C的函数原型来描述Input:对输入数据的说明Preconditions:执行本操作前系统应满足的状态/可看作初始条件Process:对数据执行的操作Output:对返回数据的说明Postconditions:执行本操作后系统的状态/“系统“可看作某个数据结构Operation2:/操作 2/ADT 抽象数据类型可以看作是描述问题的模型,它独立于具体实现。它的优点是将数据和操作封装在一起,使得用户程序只能通过在 ADT 里定义的某些操作来访问其中的数据,从而实现
12、了信息隐藏。在 C中,我们可以用类(包括模板类)的说明来表示 ADT,用类的实现来实现 ADT。因此,C中实现的类相当于是数据的存储结构及其在存储结构上实现的对数据的操作。ADT 和类的概念实际上反映了程序或软件设计的两层抽象:ADT 相当于是在概念层(或称为抽象层)上描述问题,而类相当于是在实现层上描述问题。此外,C中的类只是一个由用户定义的普通类型,可用它来定义变量(称为对象或类的实例) 。因此,在 C中,最终是通过操作对象来解决实际问题的,所以我们可将该层次看作是应用层。例如,main 程序就可看作是用户的应用程序。C+支持多范型的开发方式:面向过程,基于对象,面向对象,模版。C+和 C
13、 语言是兼容的。因此,你完全可以使用 C+编译系统编写 C 语言的程序,因此,支持面向过程编程是很自然的。但是,使用面向过程编程,还能说是在使用 C+编程吗?另外,需要注意,C+语言,实际上是一种不同于 C 语言的新语言。在内存上,除了一些C 语言的元素之外,新的语言元素并不像 C 那样面向机器。对于 C+,你不能使用 memcpy 等内存操作的函数,很可能会出现错误。因为 C+语言建立在一些高级概念的规范上,这些规范并没有规定内存如何分配等机器方面的细节。我在基于对象和面向对象编程范式辨析和主流编程语言中的应用 一文中已经指出基于对象和模板是必须组合在一起使用的技术。 C+中首选的编程范式是
14、“模板支持的基于对象”的编程范式。实现静态多态。然后才是面向对象的编程范式。实现动态多态。最后是 C 语言风格的面向过程编程。C+的使用方法使用 C/C+开发环境,我们可以同时使用 C 和 C+开发。既然 C+和 C 是兼容的,我认为完全没有理由使用 C 语言,而不使用 C+进行开发。即使是很小的问题,使用 C+的“ 模板支持的基于对象”的编程范式也是首选的开发方式。另一方面,在整个类库的外部,如果我们希望向其他语言提供接口,那么我们还应当提供C 语言的 API 函数作为接口。C 语言是程序世界的世界语。使用 C+的基本类型,struct,STL 库的 Vector,STL 的 string:
15、c_str()等都可以得到 C 语言兼容的接口。还不能使用异常。因为 C 语言不支持异常,而且 C+本身的异常,在不同的编译器中也可能不兼容。总之1,使用 C+开发,只在外部接口中使用 C 语言开发。使用 “模板支持的基于对象”的编程范式,或者面向对象的编程范式。不要使用面向过程的编程范式。2,尽量把代码放到类中,而不是使用全局或者命名空间的变量。3,尽量不要使用操作符重载。4,必须注意到 C+不像 C 语言那样面向机器,不能对 C+对象的内存布局进行假设。不能根据内存内的数据直接构建对象。不要进行内存操作。5,C+还是很面向机器的。很多语言规则都规定了内存的布局,必须按照规则定义、初始化等等
16、。这和 Java,.NET, Ruby 等语言不同。用惯高级语言的程序员特别需要注意 C+和 C 对程序员的繁琐要求。C/C+的设计哲学中,始终把自己作为一门系统编程语言,针对机器进行了很多优化。因此,对于人,就很不照顾了。很多规则很不人性化。但没办法,你必须适应它们!它们就是为了高效而生的。它们就是汇编的替代者。Java 语言优劣考Java 是一门静态强类型面向对象的编程语言。它是 C+和 Smalltalk 取长补短的产物。Java 是静态编译的强类型语言。你必须声明变量的类型,以便编译器能够检查代码的类型是否正确。这和 C+是相同的。 Java 是一门类型非常安全的编程语言。Java 只
17、支持一种编程范式:面向对象编程范式。对于过时的面向过程编程范式并不支持。也不支持基于对象的编程范式,也没有模板。原因可能是,当 java 在 90 年代中期刚刚诞生时,面向过程的编程已被唾弃。而 C+的基于对象的编程方式,由于没有和模板相互结合,而名声扫地。C+对于面向对象的编程范式的支持又比较差。于是,汲取经验教训之后, Java 作为一门纯正的面向对象编程语言诞生了。Java 使用面向对象的编程范式实现了动态多态,实现了抽象化的编程方式。取得了巨大的成功。Java 语言中,除了基本类型是值类型之外,没有任何值类型,你也不能创建任何值类型。这样,基于对象编程这条路就被卡死了。虽然丧失了值类型
18、的效率,但是也避免了基于对象编程的大量错误。Java 语言中所有方法也都是虚函数。这也是为了保证纯正的面向对象编程。Java 语言是静态面向对象编程范式的顶峰。使用面向接口的抽象编程,是有效使用 java 开发的唯一途径!另一方面,Java实际上是一门动态语言。它是动态解释执行的。和 Ruby,JavaScript 等一样。这使 java 具备了运行时的灵活性。可以实现自省,反射等 C+等传统静态语言无法实现的功能。.NET 语言优劣考.NET 是 java 的兄弟。是微软因为被 Sun 排除在 java 之外而开发的一套语言。主要包括C#,VB.net,C+/CLI 等语言。它的设计理念基本
19、和 java 相同,也是一个支持静态面向对象编程范式的平台。对于.NET 语言平台,我选择 C#和 C+/CLI 这两种语言进行论述。 VB.NET 和 C#类似,这里就不再多说了。C#C#.net 还支持值类型,也就是基于对象的编程范式。 (当然,.NET 框架也是支持值类型的)C#.net 的泛型类型替换是在运行时执行的。对于引用类型(在堆内存中创建实例的类型) ,它使用类型强制转换,而不是 C+模板的源代码生成来实现参数化类型。对于值类型,则使用类似于 C+模板的 MSIL 中间代码生成机制实现。顺便提一下,java 的泛型实现和 C#的机制类似。也是使用强制类型转换实现。而且,Java
20、 中没有值类型,也不能对基本类型进行泛型操作,因此没有 C#和 C+中的源代码扩张问题。但是,老实说,java 的泛型机制确实太弱了!C#语言首选的是面向对象编程范式。C#也可以使用泛型支持的基于对象的编程范式。使用值类型,对于用惯面向对象编程范式的 C#和 java 程序员来说有一定的难度。而且,提升的效率也并不很高。同时,在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C+ 模板的复杂性。此外,C# 并不尝试提供 C+ 模板所提供的所有功能。因此,C#泛型支持的基于对象编程要比模板支持的基于对象的编程要弱很多。理念上,泛型编程有些不伦不类,有着太强的面向对象编程的气味。C#中
21、,使用泛型支持的基于对象的编程范式不如面向对象编程范式。我认为,C#语言还是应该首先使用面向对象编程范式。C+/CLIC+/CLI 是为了让 C+使用.NET 平台而提供的扩展机制。.NET 平台是类似于 java 的静态强类型动态执行的执行平台。是面向对象编程范式理念的框架。C+/CLI 使用了新的语法,使用 C+/CLI 进行.NET 开发时,类似于 C#编程。同时,也可以使用模板进行 C+/CLI 编程。这是 C+/CLI2005 新增的功能。使用 C+/CLI 进行.NET 编程时,既可以使用 C#样式的面向对象编程。也可以使用模板支持的基于对象的编程范式进行开发。可以把模板支持的基于
22、对象的编程范式和.NET 的面向对象的编程范式结合起来使用。C+/CLI 可以同时使用原生 C+和.NET 编程。如果使用.NET 框架执行,那么 C+原生代码就会存放在生成的 MSIL 中间代码中,在运行时再使用 C+编译器编译成机器码。.NET 的互操作机制.NET 运行时本身就是使用 COM 编写的,是一个 COM 服务器。因此,.NET 和 COM 互操作是非常简单的。也可以使用 COM 技术,用 C/C+直接调用 .NET 内的方法。在互操作上。.NET 比 java 实现得更好。不能从 C 语言调用 Java 方法,只能从 java 代码中使用 JNI 调用 C 方法。总体评价.N
23、ET 是 java 的表兄弟。又做出了一下改变。1,定义了.NET 的汇编语言。基于.NET 的汇编语言可以支持任何语言在.NET 平台上执行。Java 自然也可以作为一个平台。但是 java 平台的设计目标就是 java 这一种语言,因此没有定义汇编语言,只有 java 的机器码。2,支持值类型。虽然用处不大,但是可以提高性能,也方便与 C 语言的函数库交互。3,泛型的实现比 java 强大。4,特别是 C+/CLI,具有模板*.NET 运行库的强大能力。Ruby 语言优劣考Ruby 是一种强类型的动态解释型语言。在 Ruby 中一切都是对象。使用 Duck Typing“像鸭子一样编程”的
24、编程理念。Ruby 有类型,但是变量不确定类型。这也实现了动态的多态能力。不象 Java,.NET 等静态面向对象编程语言,不需要使用什么都不作,仅仅表示类型的规范的接口。Ruby 中使用变量时不需要声明使用什么接口或者类型。任何类型都可以,只要确实有这样的方法或者数据成员存在即可!类似于 C+的模板编程,只是 C+的模板需要指定参数的类型。 Ruby 不需要指定变量的类型,因此不需要模板那样的机制。Ruby 这样不指定变量类型的语言使用起来非常灵活。按照动态语言的观点,既然编译时不能完全找出运行时的错误,不如不要编译时检查,也不要编译。使用单元测试来寻找错误。但是,C+,Java,.NET
25、这样的编译时检查类型的语言也有自己的优点:1,更加安全,编译时就会发现错误。2,可以实现 IDE 的智能提示。而 Ruby 这样的语言就不可以。因为 C+,Java 的变量使用时都指定了类型,因此可以在 IDE 中智能提示可能的成员。而 Ruby 这样的动态语言的变量都没有指定类型,所以无法为你提供智能提示。使用 Ruby,应该使用“动态类型语言”的基于对象的编程范式,使用隐式的接口。使用的类不需要有一个共同的基类。让各个实现类互相独立存在就行了。记住,这是和 C+的模板支持下的基于对象的编程范式类似的基于对象(ADT 抽象数据类型)的编程!不要试图用 java,C#这样的语言的面向对象的编程
26、思维方式来编写 Ruby 程序!JavaScript 语言优劣考JavaScript 是一门长期以来被忽视的语言。它的重要性和能力都被大大的低估了!这是因为 Java 和.NET 崛起以来, “静态类型语言”的面向对象的编程范式受到广泛的推崇。作为动态语言,函数式语言的 JavaScript 长期以来被广大 Java,.NET 程序员视为畸形怪胎!老实说,长久以来,我也一直是以厌恶的眼光看待它。多少次,它让我很抓狂。直到现在,我还是没有学好 JavaScript。尽管 JavaScript 已经诞生了这么多年,但是把JavaScript 作为一门很有前途的动态强类型语言,函数式语言来看待还是新
27、鲜事物。还没有见到很多关于这方面和设计模式的研究。周爱民的JAVASCRIPT 语言精髓与编程实践一书应该不错,但是我还没有看过。JavaScript 支持面向过程的编程范式这是 JavaScript 使用最广泛的一种编程范式。简单、快速、有效。 JavaScript 代码需要通过网络传输到用户浏览器中,因此 JavaScript 的使用一般都是简单的几个数据提交和验证功能。如果使用 Ruby 那样的动态基于对象的编程范式编码显得有些小题大做,又浪费带宽。JavaScript 支持“动态类型语言”的基于对象的编程范式如果 JavaScript 仅仅支持过时的面向过程的编程范式,那么 JavaS
28、cript 就真的是大家心目中的鸡肋了。这些年来,广大程序员都忽视了 JavaScript 也是一门动态类型语言,还是一门函数语言!我们完全可以向 Ruby 那样进行基于对象的开发。现在,伴随着广大用户对户客户端的效果和 AJAX 技术的期待。JavaScript 正在完成越来越大的任务。正在开发和传统语言类库类似的庞大类库。如,EXT 实现的用户界面库。和 Java 的 Swing 库很接近。这样巨大的系统,必须要使用基于对象的编程范式,再使用面向过程的编程范式不可想象!把 JavaScript 当成 Ruby 来使用,这是我对你的忠告。题外话:不过也许我的 JavaScript 技术永远不
29、会很高。因为虽然我越来越欣赏 JavaScript 语言的机制。但是,我对用户界面的开发并不是很有兴趣。我认为用户界面是小道。底层的逻辑开发才更有价值,我也更加有兴趣。总结现在再来看看篇首的“语言特性对比表 ”,也许你能够认同我对这些语言的观点了。如果我需要进行原生系统开发,我会选择使用 C+,使用模板支持的基于对象的编程范式进行编码。如果需要给其它语言提供接口,我会用纯 C 语言实现一些接口函数,供其它语言调用。如果需要 Java 语言进行开发,肯定要使用面向对象编程。需要大量使用接口,依赖于抽象。如果需要使用.NET 开发。那么我也会使用面向对象编程范式编码。很少使用值类型。如果使用 C+
30、/CLI 开发,我会使用模板开发原生 C+程序,也会首选模板开发.NET 程序。也可以像 C#那样使用面向对象编程范式开发.NET 程序。我真的爱死模板了!这么多年来我还一直认为模板是个废柴呢!如果要编写脚本,我会使用 Ruby, “动态类型语言”的基于对象的编程范式。Java 和.NET 平台上都在引入 Ruby,Python 等动态语言,也许很快就可以用它们开发Java 和.NET 程序了!在浏览器上开发,当然得用 JavaScript很久以前,我使用 VBScript 这门语言 上了微软的当了。那时以为凡是微软的就是好的!。简单的需求,当然用面向过程范式开发。大的项目,比如 AJAX,地图, GUI 等,使用“动态类型语言” 的基于对象的编程范式开发