前言
本文的目的并非是想挑起语言之争,而是希望通过客观地分析每一种主流语言的能力,辨明其长短,让程序员能够扬长避短,有效地使用各种语言。让各种语言能够各安其位,为你更好的服务。
程序员应当成为语言的主人,而不是语言的奴隶。
正文
这里,我将比较一下几种主流编程语言:C,C++,Java,.NET,Ruby,JavaScript。
其他主流编程语言,如Pascal,Delphi,我不太熟悉。希望熟悉的朋友能够补全对这些语言的评价。
至于Basic,它的版本差异很大,而且能力不太全面,这里也不做评价。
语言特性对比表
C C++ Java .NET Ruby JavaScript
类型
无类型
强类型
强类型
强类型
强类型
强类型
静态
/
动态
静态
静态
静态检验类型动态解释执行
动态
动态
支持面向过程
是
是
否
否
否
是
支持基于对象
否
是
否
是
是
是
支持范型
否
否
是
是
否
否
支持模板
否
是
否
否
否
否
支持面向对象
否
是
是
是
否
否
可能你对于我这样的语言评价有些疑问,请首先看我的另一篇文章《
基于对象和面向对象编程范式辨析和主流编程语言中的应用》理清相关的概念。我对与面向对象和基于对象的定义和流行的定义不太一样。
C语言优劣考
C语言由来
让我们先回顾一下历史。
电脑使用CPU指令,通过寄存器,内存等物件执行计算。最早的编程,是直接使用代表CPU指令的机器码编写的。
直接使用二进制的数据编程,当然很容易出错。
于是,人们后来发明了一种方法,就是使用英语单词作为助记符,代表各条CPU指令。
这就是汇编语言。现在,程序员可以使用英语单词进行编程,然后使用一个解释程序,把汇编指令翻译成机器语言,再交给计算机执行。
1970年,UNIX操作系统的研制者丹尼斯·里奇(Dennis Ritchie)和肯·汤普逊(Ken Thompson)为了更好地编写操作系统,发明了C语言。
C语言比汇编语言更先进。它使用了面向过程的编程范式。同时它仍是一门十分接近汇编语言,面向机器的编程语言。适合编写操作系统和其他直接操纵硬件硬件的编程。
面向过程编程范式
下面是我查到的过程式设计的定义:
过程式设计:
1、自上而下(top-down)的设计方式:是一个自顶向下,逐步求精的过程;
2、以main函数概括出整个应用程序需要做的事情,而main函数由对一系列的子函数的调用组成;
main中的每一个子函数都可以被精炼成更小的函数。重复这个过程,即可完成一个过程式的设计;
3、特征是以函数为中心,以函数作为划分程序的基本单位,数据往往处于从属地位。
过程式设计的优点:易于掌握与理解,符合人们的思维习惯;
过程式设计的缺点:
1、不能适应问题比较复杂,或者需求经常变化的情况;
2、数据与操作分离开,对数据与操作的修改变得很困难;
3、程序架构的依赖关系不合理:main函数依赖于子函数,子函数又依赖于更小的子函数;
而子函数往往是细节的实现,这些实现是经常变化的,造成的结构就是:
程序的核心逻辑依赖于外延的细节,一个细节上的小改动,会引起一系列的变动。
我对于面向过程编程范式是这样理解的:
面向过程编程,就是使用函数代表处理的过程。这些函数使用的数据,要么是参数,要么是外部的数据。
使用函数编程,这看上去很像函数式编程。但面向过程的编程范式不同于函数式编程。函数式编程的函数,一般不使用外部的数据。不维持外部的状态。这有很多优点,但也同样有了很大的局限性,不似面向过程编程这样方便。
C语言就是典型的面向过程编程语言。它通过函数抽象了过程处理。函数,就是C语言的接口。
C语言中,数据常常作为全局的变量保存起来。这样,使用C语言编程就很难保证其他代码不破坏函数依赖的数据的状态。这是C++基于对象编程范式出现的原因。这个我们稍后再说。
我们再看看C语言对机器指令的抽象。
C语言是一门十分接近汇编语言的语言。所以有人说C语言既是一门高级语言(面向过程,函数),也是一门低级语言(面向机器,直接反映计算机的实际计算过程)。
C语言使用原生类型,数组,Struct等来表示数据。C语言中,数据在内存中的表示是十分确定的。程序员可以充分控制。如,C语言中可以使用memcpy()直接复制内存中的数据。
现在,大多数的操作系统原生函数库,都使用C语言作为其接口。绝大多数的语言都具备与C语言函数库进行互操作的能力。
C语言可以说是程序世界的世界语。
C语言的优点
1, 面向过程开发,以函数为中心。简单有效。实现了简单的接口。
2, 面向机器,让用户可以完全的操纵机器,效率较高。
C语言运行高效,广泛应用于各种计算领域。对于简单的任务,非常有效。
C语言的缺点
1, 函数无法有效控制需要的数据。不能保证外部状态不变。容易出现Bug。
2, 对于机器的控制太强,也就是依赖太强。由于过于强调效率,使用C语言编程时,更多的需要考虑机器,而不是问题本身。
由于过于关注机器,而不是问题域本身,因此抽象能力不足。容易出现各种Bug。对于编写大型的程序,常常力不从心。
C语言的使用方法
C语言作为一种简单高效的编程语言,适用于编写简单的程序。在编程中,应该注意扬长避短,使用面向过程的编程范式,少用对机器的依赖。
1, 使用函数编程时,应该尽量使用函数参数传递状态,少用全局数据。因为,你无法保证全局数据不被其他代码改变。
这样使用函数,叫作“纯函数”。类似于函数式编程的用法。而且,使用这种方式编程,由于不存在全局数据,在进行多线程开发时,还不需要考虑多线程问题。
2, 使用结构化的编程方式。不要卖弄技巧。
3, 函数是接口。尽量使用函数调用,而不是直接的代码。通过层层分层,分配职责,编写出短小精悍,易于维护的代码。
4, 尽管C语言是一种面向机器的语言。但是,我们还是应该尽量少地依赖机器。多从问题域来考虑和抽象问题。如,少用内存假设等等。因为,我们会使用很多种语言,C,C++,Java,C#等语言的很多语法类似。但是实际的表现,各个语言都是不同的。如果过分考虑C的机器特性,那么很可能会因为记错而编写出错误的代码。
5, 代码,首先是给人看的。顺便给机器执行!
不要处处优化代码。只应该优化性能瓶颈。因为优化的代码,常常表示很难看懂!
6, 应该大量使用Struct组织相关的数据。在用C语言编程时,也应该树立类型和对象状态的概念。把Struct作为函数的参数传递数据。
C++语言优劣考
在C语言优劣考中曾经说过:C语言中,数据常常作为全局的变量保存起来。这样,使用C语言编程就很难保证其他代码不破坏函数依赖的数据的状态。这是C++基于对象编程范式出现的原因。
C++最初是作为C语言的扩展出现的,最初的名字就叫“带类的C”。后来,C++逐渐演化成一门独立的语言。但还是和C语言兼容。
基于对象的编程范式
基于对象的编程范式,又称“
抽象数据类型”(ADT)。
面向过程的编程范式中,函数无法控制函数外的共享数据。这使面向过程的编程语言不能很好地编写大型系统。为了解决这个问题,人们发明了基于对象的编程范式。
就是把数据和处理数据的函数都封装在一个类中。这样,共享的数据就不会再被外部的代码改变了!
下面是我查到的定义:
抽象数据类型(Abstract Type简称ADT)
ADT是指抽象数据的组织和与之相关的操作。可以看作是数据的逻辑结构及其在逻辑结构上定义的操作。
ADT的描述规范
一个ADT可描述为:
ADT ADT-Name{
Data://数据说明
数据元素之间逻辑关系的描述
Operations://操作说明
Operation1://操作1,它通常可用C或C﹢﹢的函数原型来描述
Input:对输入数据的说明
Preconditions:执行本操作前系统应满足的状态//可看作初始条件
Process:对数据执行的操作
Output:对返回数据的说明
Postconditions:执行本操作后系统的状态//"系统"可看作某个数据结构
Operation2://操作2
……
}//ADT
抽象数据类型可以看作是描述问题的模型,它独立于具体实现。它的优点是将数据和操作封装在一起,使得用户程序只能通过在ADT里定义的某些操作来访问其中的数据,从而实现了信息隐藏。在C﹢﹢中,我们可以用类(包括模板类)的说明来表示ADT,用类的实现来实现ADT。因此,C﹢﹢中实现的类相当于是数据的存储结构及其在存储结构上实现的对数据的操作。
ADT和类的概念实际上反映了程序或软件设计的两层抽象:ADT相当于是在概念层(或称为抽象层)上描述问题,而类相当于是在实现层上描述问题。此外,C﹢﹢中的类只是一个由用户定义的普通类型,可用它来定义变量(称为对象或类的实例)。因此,在C﹢﹢中,最终是通过操作对象来解决实际问题的,所以我们可将该层次看作是应用层。例如,main程序就可看作是用户的应用程序。
C++
支持多范型的开发方式:面向过程,基于对象,面向对象,模版。
C++
和
C
语言是兼容的。因此,你完全可以使用
C++
编译系统编写
C
语言的程序,因此,支持面向过程编程是很自然的。
但是,使用面向过程编程,还能说是在使用
C++
编程吗?
另外,需要注意,
C++
语言,实际上是一种不同于
C
语言的新语言。在内存上,除了一些
C
语言的元素之外,新的语言元素并不像
C
那样面向机器。
对于
C++
,你不能使用
memcpy
等内存操作的函数,很可能会出现错误。因为
C++
语言建立在一些高级概念的规范上,这些规范并没有规定内存如何分配等机器方面的细节。
C++
中首选的编程范式是“模板支持的基于对象”的编程范式
。实现静态多态。
然后才是面向对象的编程范式。实现动态多态。
最后是
C
语言风格的面向过程编程。
C++的使用方法
使用C/C++开发环境,我们可以同时使用C和C++开发。既然C++和C是兼容的,我认为完全没有理由使用C语言,而不使用C++进行开发。
即使是很小的问题,使用C++的“模板支持的基于对象”的编程范式
也是首选的开发方式。
另一方面,在整个类库的外部,如果我们希望向其他语言提供接口,那么我们还应当提供C语言的API函数作为接口。
C语言是程序世界的世界语。
使用C++的基本类型,struct,STL库的Vector,STL的string::c_str()等都可以得到C语言兼容的接口。还不能使用异常。因为C语言不支持异常,而且C++本身的异常,在不同的编译器中也可能不兼容。
总之
1,使用C++开发,只在外部接口中使用C语言开发。使用“模板支持的基于对象”的编程范式,或者面向对象的编程范式。不要使用面向过程的编程范式。
2,尽量把代码放到类中,而不是使用全局或者命名空间的变量。
3,尽量不要使用操作符重载。
4,必须注意到C++不像C语言那样面向机器,不能对C++对象的内存布局进行假设。不能根据内存内的数据直接构建对象。不要进行内存操作。
5,C++还是很面向机器的。很多语言规则都规定了内存的布局,必须按照规则定义、初始化等等。这和Java,.NET,Ruby等语言不同。用惯高级语言的程序员特别需要注意C++和C对程序员的繁琐要求。
C/C++的设计哲学中,始终把自己作为一门系统编程语言,针对机器进行了很多优化。因此,对于人,就很不照顾了。很多规则很不人性化。但没办法,你必须适应它们!
它们就是为了高效而生的。它们就是汇编的替代者。
Java语言优劣考
Java是一门静态强类型面向对象的编程语言。它是C++和Smalltalk取长补短的产物。
Java是静态编译的强类型语言。你必须声明变量的类型,以便编译器能够检查代码的类型是否正确。这和C++是相同的。Java是一门类型非常安全的编程语言。
Java只支持一种编程范式:面向对象编程范式。对于过时的面向过程编程范式并不支持。也不支持基于对象的编程范式,也没有模板。
原因可能是,当java在90年代中期刚刚诞生时,面向过程的编程已被唾弃。而C++的基于对象的编程方式,由于没有和模板相互结合,而名声扫地。C++对于面向对象的编程范式的支持又比较差。
于是,汲取经验教训之后, Java作为一门纯正的面向对象编程语言诞生了。
Java使用面向对象的编程范式实现了动态多态,实现了抽象化的编程方式。取得了巨大的成功。
Java语言中,除了基本类型是值类型之外,没有任何值类型,你也不能创建任何值类型。这样,基于对象编程这条路就被卡死了。
虽然丧失了值类型的效率,但是也避免了基于对象编程的大量错误。
Java语言中所有方法也都是虚函数。这也是为了保证纯正的面向对象编程。
Java语言是静态面向对象编程范式的顶峰。使用面向接口的抽象编程,是有效使用java开发的唯一途径!
另一方面,Java实际上是一门动态语言。它是动态解释执行的。和Ruby,JavaScript等一样。
这使java具备了运行时的灵活性。可以实现自省,反射等C++等传统静态语言无法实现的功能。
.NET语言优劣考
.NET是java的兄弟。是微软因为被Sun排除在java之外而开发的一套语言。主要包括C#,VB.net,C++/CLI等语言。
它的设计理念基本和java相同,也是一个支持静态面向对象编程范式的平台。
对于.NET语言平台,我选择C#和C++/CLI这两种语言进行论述。VB.NET和C#类似,这里就不再多说了。
C#
C#.net还支持值类型,也就是基于对象的编程范式。(当然,.NET框架也是支持值类型的)
C#.net的泛型类型替换是在运行时执行的。对于引用类型(在堆内存中创建实例的类型),它使用类型强制转换,而不是C++模板的源代码生成来实现参数化类型。
对于值类型,则使用类似于C++模板的MSIL中间代码生成机制实现。
顺便提一下,java的泛型实现和C#的机制类似。也是使用强制类型转换实现。而且,Java中没有值类型,也不能对基本类型进行泛型操作,因此没有C#和C++中的源代码扩张问题。
但是,老实说,java的泛型机制确实太弱了!
C#语言首选的是面向对象编程范式。C#也可以使用泛型支持的基于对象的编程范式。
使用值类型,对于用惯面向对象编程范式的C#和java程序员来说有一定的难度。而且,提升的效率也并不很高。
同时,在语法层面上,C# 泛型是实现参数化类型的更简单方法,不具有 C++ 模板的复杂性。此外,C# 并不尝试提供 C++ 模板所提供的所有功能。
因此,C#泛型支持的基于对象编程要比模板支持的基于对象的编程要弱很多。
理念上,泛型编程有些不伦不类,有着太强的面向对象编程的气味。
C#中,使用泛型支持的基于对象的编程范式不如面向对象编程范式。
我认为,C#语言还是应该首先使用面向对象编程范式。
C++/CLI
C++/CLI是为了让C++使用.NET平台而提供的扩展机制。
.NET平台是类似于java的静态强类型动态执行的执行平台。是面向对象编程范式理念的框架。
C++/CLI使用了新的语法,使用C++/CLI进行.NET开发时,类似于C#编程。
同时,也可以使用模板进行C++/CLI编程。这是C++/CLI2005新增的功能。
使用C++/CLI进行.NET编程时,既可以使用C#样式的面向对象编程。也可以使用模板支持的基于对象的编程范式进行开发。
可以把模板支持的基于对象的编程范式和.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方法。
总体评价
.NET是java的表兄弟。又做出了一下改变。
1,定义了.NET的汇编语言。基于.NET的汇编语言可以支持任何语言在.NET平台上执行。Java自然也可以作为一个平台。但是java平台的设计目标就是java这一种语言,因此没有定义汇编语言,只有java的机器码。
2,支持值类型。虽然用处不大,但是可以提高性能,也方便与C语言的函数库交互。
3,泛型的实现比java强大。
4,特别是C++/CLI,具有模板*.NET运行库的强大能力。
Ruby语言优劣考
Ruby是一种强类型的动态解释型语言。在Ruby中一切都是对象。
使用Duck Typing“像鸭子一样编程”的编程理念。Ruby有类型,但是变量不确定类型。这也实现了动态的多态能力。
不象Java,.NET等静态面向对象编程语言,不需要使用什么都不作,仅仅表示类型的规范的接口。Ruby中使用变量时不需要声明使用什么接口或者类型。
任何类型都可以,只要确实有这样的方法或者数据成员存在即可!
类似于C++的模板编程,只是C++的模板需要指定参数的类型。Ruby不需要指定变量的类型,因此不需要模板那样的机制。
Ruby这样不指定变量类型的语言使用起来非常灵活。
按照动态语言的观点,既然编译时不能完全找出运行时的错误,不如不要编译时检查,也不要编译。使用单元测试来寻找错误。
但是,C++,Java,.NET这样的编译时检查类型的语言也有自己的优点:
1,更加安全,编译时就会发现错误。
2,可以实现IDE的智能提示。而Ruby这样的语言就不可以。因为C++,Java的变量使用时都指定了类型,因此可以在IDE中智能提示可能的成员。
而Ruby这样的动态语言的变量都没有指定类型,所以无法为你提供智能提示。
使用Ruby,应该使用“动态类型语言”的基于对象的编程范式,使用隐式的接口。使用的类不需要有一个共同的基类。让各个实现类互相独立存在就行了。记住,这是和C++的模板支持下的基于对象的编程范式类似的基于对象(ADT抽象数据类型)的编程!
不要试图用java,C#这样的语言的面向对象的编程思维方式来编写Ruby程序!
JavaScript语言优劣考
JavaScript是一门长期以来被忽视的语言。它的重要性和能力都被大大的低估了!
这是因为Java和.NET崛起以来,“静态类型语言”的面向对象的编程范式受到广泛的推崇。作为动态语言,函数式语言的JavaScript长期以来被广大Java,.NET程序员视为畸形怪胎!老实说,长久以来,我也一直是以厌恶的眼光看待它。多少次,它让我很抓狂。
直到现在,我还是没有学好JavaScript。尽管JavaScript已经诞生了这么多年,但是把JavaScript作为一门很有前途的动态强类型语言,函数式语言来看待还是新鲜事物。还没有见到很多关于这方面和设计模式的研究。
周爱民的《JAVASCRIPT语言精髓与编程实践》一书应该不错,但是我还没有看过。
JavaScript支持面向过程的编程范式
这是JavaScript使用最广泛的一种编程范式。简单、快速、有效。JavaScript代码需要通过网络传输到用户浏览器中,因此JavaScript的使用一般都是简单的几个数据提交和验证功能。如果使用Ruby那样的动态基于对象的编程范式编码显得有些小题大做,又浪费带宽。
JavaScript支持“动态类型语言”的基于对象的编程范式
如果JavaScript仅仅支持过时的面向过程的编程范式,那么JavaScript就真的是大家心目中的鸡肋了。
这些年来,广大程序员都忽视了JavaScript也是一门动态类型语言,还是一门函数语言!
我们完全可以向Ruby那样进行基于对象的开发。
现在,伴随着广大用户对户客户端的效果和AJAX技术的期待。JavaScript正在完成越来越大的任务。正在开发和传统语言类库类似的庞大类库。
如,EXT实现的用户界面库。和Java的Swing库很接近。这样巨大的系统,必须要使用基于对象的编程范式,再使用面向过程的编程范式不可想象!
把JavaScript当成Ruby来使用,这是我对你的忠告。
[题外话:
不过也许我的JavaScript技术永远不会很高。因为虽然我越来越欣赏JavaScript语言的机制。但是,我对用户界面的开发并不是很有兴趣。我认为用户界面是小道。底层的逻辑开发才更有价值,我也更加有兴趣。
]
总结
现在再来看看篇首的“语言特性对比表”,也许你能够认同我对这些语言的观点了。
如果我需要进行原生系统开发,我会选择使用C++,使用模板支持的基于对象的编程范式进行编码。
如果需要给其它语言提供接口,我会用纯C语言实现一些接口函数,供其它语言调用。
如果需要Java语言进行开发,肯定要使用面向对象编程。需要大量使用接口,依赖于抽象。
如果需要使用.NET开发。那么我也会使用面向对象编程范式编码。很少使用值类型。
如果使用C++/CLI开发,我会使用模板开发原生C++程序,也会首选模板开发.NET程序。也可以像C#那样使用面向对象编程范式开发.NET程序。
我真的爱死模板了!这么多年来我还一直认为模板是个废柴呢!
如果要编写脚本,我会使用Ruby,“动态类型语言”的基于对象的编程范式。
Java和.NET平台上都在引入Ruby,Python等动态语言,也许很快就可以用它们开发Java和.NET程序了!
在浏览器上开发,当然得用JavaScript[很久以前,我使用VBScript这门语言—上了微软的当了。那时以为凡是微软的就是好的!。
简单的需求,当然用面向过程范式开发。
大的项目,比如AJAX,地图,GUI等,使用“动态类型语言”的基于对象的编程范式开发。
评论
-
#vironica 发表于2008-06-10 11:15:43 IP: 58.60.138.*
- 楼主是.net阵营,对非C,C++评价有偏失 #MangDong 发表于2008-06-10 11:18:03 IP: 203.86.72.*
- 这些与其说是各种主流编程语言考,不如说是作者自己之所爱流水账。使用哪一种语言并不是很重要,关键是在要在那个领域内使用。是跨平台,是本地还是网络,是嵌入还是桌面抑或网站,不同的领域不同的需求决定究竟是采用哪一种语言,或者混合语言编程都是有可能的.一概而论,说那种语言好那种语言差,那种编程规范好,那种差,不论说多说少,说好说次都是不合适的.没有绝对的好也同样没有绝对的差,因时因地具体问题具体分析.一个优秀不也许是卓越的程序员, 决不会拘泥于哪一种语言,束缚于哪一种范式,他只会在合适的领域采用合适的语言,运用合适的范式,做合适的工作.如果你做不到,那说明你也许仅仅优秀根本称不上卓越,努力方向也许就在于此. #Mailbomb 发表于2008-06-10 11:19:35 IP: 125.40.47.*
- Java完全支持面向过程的编程和基于对象的,别的不好评价 #sudamj 发表于2008-06-10 11:26:16 IP: 58.240.178.*
-
C++不支持范型?????
你昏了头了吧?Loki库 Boost库 没听过?》
#shendl 发表于2008-06-10 11:34:11 IP: 58.39.186.*
-
#sudamj 发表于2008-06-10 11:26:16 IP: 58.240.178.*
C++不支持范型?????
====================
C++那是模板,不是泛型。模板是编译时通过生成源代码实现的。
泛型是Java和.NET使用的,是运行时通过类型转换实现的。
泛型的能力远远小于模板。
使用的理念也不同。泛型往往使用接口来规范类型,还是使用面向对象的编程思路。
#shendl 发表于2008-06-10 11:37:05 IP: 58.39.186.*
-
#Mailbomb 发表于2008-06-10 11:19:35 IP: 125.40.47.*
Java完全支持面向过程的编程和基于对象的,别的不好评价
=========================
如果使用面向过程的方法写Java程序,那么这个程序员不合格!
用Java基于对象编程,那么怎么实现多态,怎么实现依赖抽象?
请看《基于对象和面向对象编程范式辨析和主流编程语言中的应用》一文,静态语言没有模板进行基于对象的编程,那会是一团糟~!
#shendl 发表于2008-06-10 11:38:52 IP: 58.39.186.*
-
#vironica 发表于2008-06-10 11:15:43 IP: 58.60.138.*
楼主是.net阵营,对非C,C++评价有偏失
=======================
我是Java阵营的。使用Java进行面向对象编程很舒服。但缺点就是缺点,遗憾就是遗憾。
#shendl 发表于2008-06-10 11:42:53 IP: 58.39.186.*
-
回复:#MangDong 发表于2008-06-10 11:18:03 IP: 203.86.72.*
=============================
很久以来,我一直听到高手有这样的观点:写到一定的程度,语言并不重要。任何语言都可以。
我一直都反对这样的观点。每种语言的设计思路和哲学观点都是不同的。它们的区别并不仅仅是关键字上的区别!
每种语言有最适合的不同的编程范式。如果不能因语言而变使用的方法,怎么能写好程序呢?!
编程语言不仅仅是一门语言,更是一种编程哲学的体现!
#iwad 发表于2008-06-10 12:14:15 IP: 210.14.93.*
-
……C语言的缺点:
由于过于关注机器,而不是问题域本身,因此抽象能力不足。容易出现各种Bug。对于编写大型的程序,常常力不从心。……
~~~~~~~~~~~~~~
这句话说的太对了。C语言也就能写写linux、windows这样的小程序,对于大型的程序,根本无能为力……
#chaochaoli 发表于2008-06-10 13:04:07 IP: 125.47.49.*
- 这几种语言你一种有前途呀 #Sonic2007 发表于2008-06-10 13:20:21 IP: 218.80.228.*
-
有地方写的不对
严格来说, 模板与泛型可以互操作
java中没有值类型也不完全对
#DragonTang 发表于2008-06-10 14:01:22 IP: 220.189.165.*
-
2003.9-2004.3 我使用C语言开发金融系统,
2004.3-至今,我使用JAVA语言开发网页和应用系统.
#shendl 发表于2008-06-10 15:03:49 IP: 58.39.186.*
- Java中只有基本类型是值类型。你不能自定义一种值类型。 所谓值类型,就是在栈中分配内存的类型;所谓引用类型就是在堆中分配内存的类型。 #shendl 发表于2008-06-10 15:22:08 IP: 58.39.186.*
-
#chaochaoli 发表于2008-06-10 13:04:07 IP: 125.47.49.*
这几种语言你一种有前途呀
============================
只要正确使用,上面这些语言都有前途。我平时喜欢用Java写程序,对.NET下的C++/CLI语言有兴趣。Ruby是未来很有希望的语言。JavaScript,任何程序员都离不开它!
#maple1988 发表于2008-06-10 16:56:40 IP: 61.128.234.*
- 初学者,感受不深 #easydesk 发表于2008-06-10 17:11:31 IP: unknown, 203.*
-
javascript只是网页编程的附属品。
真正的程序员还是用C,操作系统一般都是C语言编写,驱动程序也是用C语言写,楼主好像搞错了,C语言是真正面向问题的,不是面向机器的。
#heimirror 发表于2008-06-10 17:36:52 IP: 123.115.128.*
- 只对.NET javascript 了解,看来楼主的文章受教了。 #flexitime 发表于2008-06-10 17:54:06 IP: 218.20.201.*
-
C++没有泛型!???
无语中,
自己上网找找,讲C++的泛型书多到可以压死人。无论是C#还是Java都是从C++中学来泛型的,反正“迭代器”这个词我就是从C++中学回来的
#bingg 发表于2008-06-10 18:23:44 IP: 59.40.222.*
- 严重不同意LZ 的观点.谁说面向对象的语言就不支持面向过程了啊. #cc555 发表于2008-06-10 20:11:59 IP: 58.37.250.*
- .net #fsdsws 发表于2008-06-10 20:52:23 IP: 60.166.204.*
- c#java看起来舒服 #yjfh_007 发表于2008-06-10 21:44:12 IP: 117.22.187.*
- C#掩盖了太多内部机制,用它编程总有意犹未尽的感觉。但不可否认它很好用! #napoloen288 发表于2008-06-10 23:56:15 IP: 218.66.14.*
- 受教了,c# java。。。 #iwillalwaysloveyou 发表于2008-06-11 00:13:33 IP: 123.117.173.*
-
2, 对于机器的控制太强,也就是依赖太强。由于过于强调效率,使用C语言编程时,更多的需要考虑机器,而不是问题本身。
由于过于关注机器,而不是问题域本身,因此抽象能力不足。容易出现各种Bug。对于编写大型的程序,常常力不从心。
纯粹是胡扯八道,楼猪你用过C语言吗?
#fohoo 发表于2008-06-11 01:03:26 IP: 59.42.190.*
-
楼主的C/C++水平还是个门外汉,装摸做样的拿C/C++显摆,贻笑大方事小,误人子弟就不好了
C就不能使用面向对象的方法来设计了?去看看GDK的设计吧。
你说的“对于C++,你不能使用memcpy等内存操作的函数,很可能会出现错误”,对于哪些雾里看花的Javaer们,确实是这样。
#yshuise 发表于2008-06-11 08:09:36 IP: 202.106.149.*
- 模板编程就是泛型编程。大哥!!!! #leojay 发表于2008-06-11 09:52:47 IP: 58.37.247.*
-
1. C的无类型是什么意思?
2. 你对模板和泛型的理解有误。
泛型编程就是Generic programming,在wikipedia中的解释为:Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters.
http://en.wikipedia.org/wiki/Generic_programming
你说C#和java不支持模板,就更是错误了。
#scengion 发表于2008-06-11 10:25:01 IP: 218.6.192.*
- 计算机语言只是实现目的工具,重要的是思路 #developCpp 发表于2008-06-11 10:32:13 IP: 58.241.130.*
-
脚本语言竟然没有提Perl,Python,PHP
另外这篇文章充分证明了楼主对C,C++,Java,.NET的无知
只是对Ruby懂点皮毛
#mapserver 发表于2008-06-11 11:01:02 IP: 124.78.99.*
-
ruby不支持面向对象,简直是扯淡。
不懂还胡说一通。
#shendl 发表于2008-06-11 12:21:43 IP: 211.144.96.*
-
楼上的,我无语了!
你没看《基于对象和面向对象编程范式辨析和主流编程语言中的应用》这篇文章瞎叫唤啥呀?!
我的定义中,有接口实现的,那叫面向对象。其他都是基于对象。
我真的无语了!!!
#shendl 发表于2008-06-11 12:23:34 IP: 211.144.96.*
-
#leojay 发表于2008-06-11 09:52:47 IP: 58.37.247.*
1. C的无类型是什么意思?
2. 你对模板和泛型的理解有误。
泛型编程就是Generic programming,在wikipedia中的解释为:Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters.
http://en.wikipedia.org/wiki/Generic_programming
你说C#和java不支持模板,就更是错误了。
==============================================================================================
大家使用的定义不同。你看Visual Studio里的帮助,我采用的是那里的定义!
#shendl 发表于2008-06-11 12:25:39 IP: 211.144.96.*
- 原来泛型和模板这2个概念可以混用。但是,C#和Java推出了不同于C++的模板的泛型之后。就不能再混用泛型和模板这2个概念了。 #leojay 发表于2008-06-11 12:50:39 IP: 58.37.247.*
-
我还是认为是你的理解不对。即便C#和Java的模板与C++的模板不同。但泛型的概念还是没有变。你可以看看msdn里的An Introduction to C# Generics这篇文章。
http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx
#djsl6071 发表于2008-06-11 13:18:48 IP: 59.59.6.*
-
基于对象和面向对象这两个概念的划分,lz的依据是多态,也就是接口编程,而把继承作为独立于编程范式之外的行为。我更认为继承是面向对象的基础,应该作为区分的依据,而多态编程,是java尝试替代c++虚函数和模板编程的手段,由于值类型和引用类型的差异,这一手段缺乏效率和不够简洁,否则将可以在面向对象的绝对范畴中替代泛型。在此前提下,不得不实现了“软”泛型,lz很明确地区分泛型和模板编程,在我看来,泛型就是超级范式,对算法的抽象和无关类型参数的处理复用,而模板,正是c++等实现这一目的的手段。
“动态多态”的概念好像是指动态语言中对运行时修改类型行为的能力,不熟。
#caicai_45 发表于2008-06-11 13:24:35 IP: 219.141.219.*
- .NET的泛型实现是在编译期优化的,已经确认了类型了,不是在运行时强制类型转换的............. #sleepynow 发表于2008-06-11 14:04:43 IP: 116.231.49.*
- 一个鄙视楼主的Cer路过。。。 #shendl 发表于2008-06-11 15:25:39 IP: 211.144.96.*
-
继承是一种代码重用技术,与多态无关。我倾向于使用组合来代替继承。
“动态多态"指的是在运行时确定真正的类型。如Java,.NET使用接口实现的多态。
“静态多态”值的是C++的模板这样的机制。在编译时就确定了真正的类型。
#shendl 发表于2008-06-11 15:27:30 IP: 211.144.96.*
- 至于模板和泛型的概念。 大家定义不同,无法争论。如果你学过Java或者.NET,以及C++。就会知道Java和.NET的泛型实现和C++的模板是本质不同的。只是语法形式上有些类似而已! #GoAssemblyNow 发表于2008-06-11 15:31:22 IP: 125.122.54.*
- 看不大懂,飘过。 #nrbk100 发表于2008-06-11 16:01:46 IP: 61.232.14.*
-
对于楼上的各位我觉的大家可以对学术讨论,但是对楼主进行人生攻击也太不厚道了吧?
严重BS
至于楼主说的对错与否起码是个抛砖引玉之言.虽然有写地方我不是很同意,但是整个文章还是值得肯定的.
有本事你也去写一篇来啊?楼主学过的语言过多,难免有不是很精通的东西,我觉得无以厚非.
#shendl 发表于2008-06-11 16:51:41 IP: 211.144.96.*
-
关于模板和泛型,年初的时候我还是抱着错误的观点的。那时,我把C++的模板当作Java的泛型来使用。强烈要求C++的模板和泛型一样限制可用的类型。当时的我的想法是,C++模板应该提供限制参数类型的语法。
后来,我才发现我错了。 模板和泛型根本就是2种不同的编程范式的语法。 模板比泛型更强,而不是相反。 年初的文章是《C++的泛型编程和限制参数类型的技术探讨 》 http://blog.csdn.net/shendl/archive/2008/01/12/2040031.aspx 那篇文章中,泛型和模板我是当作一个概念使用的!
#dyh7220335 发表于2008-06-11 17:44:12 IP: 221.11.66.*
- 我是小菜鸟,大概看看,,各位都是大哥,,我慢慢学,,,定立目标,苦学1年,,,在这1年里,论坛会经常出现我身影,,这是来了论坛,发的第一篇评论,,,大学没学好,,现在来补课,,,各位大哥以后多帮忙哈 #richbirdandy 发表于2008-06-11 17:59:35 IP: 219.140.154.*
- 我第一次听说C++不支持泛型 如果lz对泛型不理解 就不要谈这个词了 #wubctx 发表于2008-06-11 18:11:23 IP: 59.111.108.*
- 学习一下! #dazhuaye 发表于2008-06-11 22:51:45 IP: 58.49.138.*
-
有点奇怪~!`
C++不支持范型!`
不知道C++的范型编程是从那来掉下来的~!`呵呵`!
#gghunter 发表于2008-06-11 23:04:55 IP: 125.91.127.*
- javascript应该是弱类型吧,而且和前面几种做比较的话,简直是无稽之谈.大家面向的方向不同,没什么比较性. #z2007b 发表于2008-06-12 00:51:44 IP: 59.40.114.*
-
楼主大爷.不懂不是错.出来装懂吓唬人就不对了.
你说C不支持面向对象.
看起来好像是这么一回事.
可是我想说那是因为个人的原因.
C完可以模拟出任何"JAVA这种正宗的面向对象语言"的一切!!包括JAVA引以为豪的正宗的面向对象.
另外有一个观点你好像又错了:
你好像认为JAVA和.NET是一回事.
哎.
JAVA是一种跨平台的语言.其倡导是:一次编译到处运行.其根本是通过一个不跨平台的JVM来实现其跨平台.
而.NET则是反其道行之.他的目的是让所有的语言都能在.NET这个平台上运行.根本是两码子事.
另外还想说一句.
C和汇编是计算机的基石也是根本.
用JAVA和.NET做网站的朋友是很难接触到内核机制这些的.
最"可贵"的是JAVA中的内存是不需要释放的.是解决了一个相当大的难题.我承认.可是同志们啊.这和小孩子不会擦屁股爸妈帮他擦有啥区别呢?如果不加以纠正.我想这个孩子可能永远都不会擦屁股.甚至都不知道有擦屁股这回事.
JAVA做为一种商业产品,是成功的.他非常成功的屏蔽了底层的细节.可做为一位专业的敲代码的同志如果敲了三四年还不知道下面到底干了些啥.自已到底new了一些什么东西,这才可悲.
#DRACULAX05 发表于2008-06-12 09:39:20 IP: 119.145.0.*
- 又一个坑,又有那么多人跳,鉴定完毕 #cc555 发表于2008-06-12 10:25:54 IP: 118.26.231.*
-
这句话说的太对了。C语言也就能写写linux、windows这样的小程序,对于大型的程序,根本无能为力……
---------
linux、windows是小程序?????
oh,my god!!!
#onemonth 发表于2008-06-12 10:33:28 IP: 125.85.139.*
-
楼主不过把语言某些特点google了一下,然后摆在这里。从描述来看,楼主不懂怎样用c做设计,再看对c++的说法,同样对现代c++根本不明白。顺便看了楼主的链接,如下代码
Template<tyepe TDao >Class Service{
Private:
TDao* dao=new TDao();
Public:
Void save(Model model){
This->dao->save(model);
}
}
这样的设计,只能让人吐。
再看你对ruby的说法,显然你没有用过ruby的IDE。
#apoclast 发表于2008-06-12 17:25:42 IP: 222.44.160.*
-
javascript居然变成强类型了...
LZ真博学
.net也不是动态解释运行,而是在生成应用程序时先翻译成MSIL语言,在运行的时候再编译为机器语言,应用程序启动以后就不存在解释这个操作了
#shendl 发表于2008-06-12 17:58:39 IP: 211.144.96.*
-
Java和.NET编译成的字节码,是一种虚拟的机器码。还可以看作是源代码。运行时,虚拟机解释这些源代码,并生成机器码,然后执行。 Basic,Ruby等解释型语言,每次生成的机器码执行完毕后就会丢弃。下次再执行相同的代码,还需要再次解释。 Java和.NET后来引入的JIT即时编译方案,就是首次解释后生成的机器码留着,下次再执行相同的代码时,不再解释,而是直接使用已有的机器码。
Ruby等动态语言为了提高效率,也在考虑使用JIT方式执行代码。
楼上的老兄连.NET和Java的动态运行本质都搞不清楚,真是可怜!
#legend2049 发表于2008-06-12 22:39:51 IP: 119.122.96.*
-
我觉得语言只需要好好的学通学精一门就可以了
另外,每个语言都有他自己的舞台
#MagiSu 发表于2008-06-13 01:13:41 IP: 218.104.71.*
-
楼主,不是我说你:
1、你放弃通用的标准,非要自己定义一套新名词,何必呢?
2、你对C/C++了解么?无论Unix,BSD,Linux,Windows哪个大型系统不是用C写的?
3、C++支持范型是不争的事实,你非要自己给范型下个定义自说自话,拜托到火星说火星文,到地球说地球文行不?
4、C可以做面向对象,具体看Ojbect Orient Programming in C,1994年就出版了。只是方法比较繁琐罢了。
5、楼主缺乏C++应用经验,完全没看过(至少没看懂)STL。memcpy可以用,自己看inside C++,里面就有例子。“但是,使用面向过程编程,还能说是在使用C++编程吗?”更是扯蛋,语言提供的机制凭什么不能用?面向过程同样是C++的一个重头,自己读读boost::graph的代码,恰恰是这样的基于模板的面向过程为程序提供了广泛的应用。
6、你永远不可能统统精通这些语言,最好的办法是找个精通的人合作,而不是仗着自己的皮毛知识来鬼扯。
#sibylle 发表于2008-06-13 09:01:03 IP: 61.187.56.*
-
我仔细看了作者关于语言的这两篇文章,还是有不少收获的。
后面的争论主要围绕作者的两个观点,一个是C不支持面向对象,一个是C++不支持泛型。
个人觉得这两个观点其实已经背离了作者写这文章的本意,作者辛苦码了这么多文字,重点在于记录多年开发的心得和以前对语言理解的误区,写的很真挚,我们应该尊重作者的劳动。
至于有争议的两个问题,我提出我的观点:
1.C支不支持面向对象:首先C是一门语言,在语言层次上,C并不能为面向对象提供多少的支持,所以说C不支持面向对象是可以的。但是面向对象是一种设计哲学,你硬要用C来实现面向对象也不是不行,我以前粗粗看过Ojbect Orient Programming in C,里面提到的是用结构体来代替类,全局函数来实现类的功能,该书的重点在于,如何在C语言本身没有提供面向对象支持的情况下,在C的开发中使用面向对象的优点,而不是鼓励大家在开发C语言的时候用面向对象语言。同理,能不能在C++中memcpy也是一个道理,可以参照侯捷老师的《深度探索C++对象模型》,里面对C++的内存结构有深入分析,在了解C++的内存结构后,你可以用memcpy,但是我相信,很少有人会这么做。所以我觉得,作者说C++不能用memcpy也是正确的。
2.至于C++支不支持泛型,我没有什么发言权,因为我也没有深入的学习过。但是我知道,如果没有看作者第一篇文章,肯定第一印象的感觉是作者错了。但看了作者第一篇文章,就可以了解到,作者是从一个新的角度看问题,提出了自己的论点。也许作者写C++的泛型和java的泛型概念不一样更为精确。
我们提倡辩,不提倡批,平和一点,谦虚一点,看到作者的劳动,一起把问题弄清,这才是我们追求的重点!希望作者继续努力,能继续写篇文章,将C++和java的泛型的区别介绍清楚,我很期待。
另:不知道当前《Ojbect Orient Programming in C》的文章,如果出现在CSDN上,会被砸成怎样:)
#sxcong 发表于2008-06-13 09:41:52 IP: 58.241.135.*
-
c支持对象,最典型的例子就是struct中使用函数指针。
看来作者对这些语言还不是很深入。记得有个大师写了本书叫c++批判,绝大多数c++程序员都很赞赏。
不管是批判还是夸奖某种语言,一定要很精通才有说服力。等到那时再写这类的文章会更好
#shendl 发表于2008-06-13 10:24:14 IP: 211.144.96.*
- 多谢#sibylle 兄中肯的支持。 有时间我会另写一篇文章,详细分析C++的模板和Java,以及.NET的泛型。 其实,分析模板和泛型的文章,我早就想写了。 最近公事、私事比较多,所以很久没写Blog了。 #shendl 发表于2008-06-13 10:32:18 IP: 211.144.96.*
-
用C模仿对象编程,我当然会了。 但是,我手头的常用的编译器是VC++。它既支持C,也支持C++。我脑子抽了,有C++的对象支持不用。 硬用Struct和全局函数模拟基于对象编程?
而且,我认为基于对象的编程必须有C++的模板的配合才能发挥巨大的作用。单纯基于对象,不能实现多态,不能实现抽象的设计! C可是没有模板机制的!
C本来就不是为了基于对象的编程范式开发的,你硬要用基于对象的范式开发,也无不可;甚至你不用结构化编程方法,用GOTO写天书,亦无不可!
我谈的只是我的经验,我的编程感悟。不期待每一个人都赞同。 特别是,看《 基于对象和面向对象编程范式辨析和主流编程语言中的应用》这篇文章的人不到1/10。令我心寒!!! 这就是国内程序员浮躁心态的表现啊!!!