作者:Michael Lee 来源:博客园   酷勤网收集 2008-03-04

摘要
  一、语言的分类;二、语言是"苍白无力"的;三、语言和工具要分清;四、开发工具是什么?五、学习一门程序语言很难吗?六、语言、开发方法和设计模式的关系?

一、语言的分类

语言的分类,每个人都有自己的角度,划分不一而足。我个人的看法是分为两大类,面向过程的语言和面向对象的语言。面向过程的语言,注重逻辑过程的描述,面向对象的语言在过程基础上加入了对象的描述和操作的相关语法。

典型的面向过程语言有:C、Pascal、汇编等等。对于过程的描述一般是分支和循环(顺序执行是必需的,不用说。)。对于分支又分为二路分支和多路分支。典型的二路分支:if……else……当然也有单个if的情况。多路分支通常是指switch……case,或者if……else if……else的情况。循环也是分为两种:while循环和do……while……循环。通常while循环可以和for循环互相等价转化,所以他们是一类的。do……while……循环的主要特点是先执行再判断,而while循环是先判断再执行。

典型的面向对象的语言有:C++、C#、Java等等,通常是在面向过程的语言基础上加入了面向对象的语法特性,比如:C++、面向对象的Pascal,当然像C#、Java等不在此列。面向对象的语言肯定都包含了面向过程的描述分支、循环一个都不少。同时也含有面向对象的特性。支持封装、继承、多态是所有OO 语言共同特性。所谓封装,就是限制了对象外部队对象的成员访问的权限,通常支持的有public、private、protected三种,这里就不赘述了。继承是指派生类可以使用父类的代码遗产,实现部分的代码和功能复用(相当浅薄的解释,一句话说清楚很不容易,敬请谅解)。多态是指子类在集成了父类的定义的"接口"基础上实现不同的行为(这个也很难一句话说清楚,敬请谅解)。这些大家都耳熟能详了,但还有一个共同特性可能大家忽略了。那就是,支持OO的语言普遍都支持异常的捕捉和处理。这也是一个成熟的OO语言所必需的。但是面向过程的语言基本上对此都不支持。

二、语言是"苍白无力"的


一切计算机的语言的功能仅限于对于执行逻辑的描述。但语言本身不具备执行的能力。为啥这么说呢?一般来说,大家初学某种编程技术的时候都会先接触HelloWorld的例子。这个例子可以说是世界上最牛的程序例子了,占据着拷贝量最大、散布最广、运行最稳定、版本最多(因为语言种类多啊)等多项第一。就拿C++、C#、Java来说吧:
C++版本:
main()
{
cout<<"Hello World"<<endl;
}
C#版本:
public static void Main()
{
System.Console.WriteLine("Hello World");
}
Java版本:
public static void main(String args[])
{
System.out.println("Hello World")
}
提请大家注意,这三个版本的Hello World程序,完成"Hello World" 字符串输出的都不是语言,而是库函数。cout、Console、out这三个并不是各自语言中的保留字,如果您把他们当作一个库函数的类在文档中检索,到是能查得到。我举这个例子,是要说明写程序单单要掌握语言是远远不够的。更具有挑战性的学习是掌握一套某种语言可以调用的函数库。要想使用C语言写程序,起码要能灵活使用CRT;使用C++语言写程序,需要掌握CRT、STL、ATL、Boost等一种或几种(C++的库最多也最乱,光STL就有n多个版本)。如果您使用VB.NET或者C#、Java那就恭喜您了,因为功能您选择和学习的库都是有且仅有一种。语言离开了库函数的支持,什么也做不了,所以我说语言是"苍白无力"的。

三、语言和工具要分清


很多情况下,您可能会听到这样的对话:
问:"你用什么语言做开发?" 答:"我用Visual C++"
殊不知Visual C++是微软出品的可视化开发工具,而C++才是程序语言。人家问语言,你回答工具,严格地说就是驴唇不对马嘴。但现在人们接受且习惯了这种说法。以上混淆发生在几乎市面上流行的所有的开发工具和程序语言中。列举几个:
1) Delphi 是一种Borland出品的RAD开发工具,该工具所使用的程序语言是面向对象的Pascal;
2) C++ Builder、Visual C++是Borland和微软出品的基于C++的可视化开发工具,当然这两个工具所使用的程序语言是C++;
3) Visual Studio 系列也是微软出品的开发工具,而C#、VB.NET才是程序语言;
……

四、开发工具是什么?

从本质上讲,开发工具主要由三部分构成,开发界面、编译器、函数库。而编译器和函数库再加上一部分开发所必需的文档就构成了另外一个东东叫做SDK(发现很多人都没有客观的解释一下SDK,只是把缩写展开摆上三个单词)。当然,您也可以说,开发工具是由开发界面和SDK两部分构成。
列举几个典型的例子:
Visual Studio系列:
开发界面大家都很熟悉了,包括Solution Explorer、Class Explorer以及工具箱,代码编辑界面等等。编译器包含了C#编译器(csc.exe)、C++编译器(cl.exe)等等。函数库包括.NET Framework class library,CRT,MFC,ATL等等。其实,Visual Studio系列就包含了.NET SDK 和Window Platform SDK(主要是C++编译器、Windows API等等)。
Eclipse系列:
开发界面同样也包括类浏览器、CVS浏览器、代码编辑界面等等。编译器包含了Java编译器,函数库主要是JDK所带的API。Eclipse包含了JDK也就是Java SDK。
通常情况下,各家常常的SDK都是免费的,也就是说您可以合法的,免费的从厂商的官方网站上获取语言的编译器和相关的库函数以及开发文档。开发工具真正卖钱的其实就是那个开发界面。如果您能保证自己在记事本中浏览几千行代码而不眼晕并对编译器的各种编译参数都了如指掌的话,您完全可以通过免费的方式光明正大的编写您自己的程序(毕竟Notepad是随OS自带的,您已经为此付过钱了)。

五、学习一门程序语言很难吗?

 


如果仅仅是语言本身的话,很简单。因为通过上面的总结,您已经了解了语言基本包含的内容。您从一门程序语言转换到另一门程序语言可能仅仅需要适应大小写是否敏感、边界使用大括号表示还是用Begin……End表示等等杂项,估计有一两个星期,怎么也适应了。如果您想用这门程序语言随心所欲的编写程序,那么就是一个比较艰苦和漫长的过程了,因为您要至少熟悉一套庞大的函数库。

 

六、语言、开发方法和设计模式的关系?

我个人认为,程序语言是描述执行逻辑的基础。开发方法属于方法论范畴,到底是使用瀑布模型还是螺旋模型?这都是形而上的东东,对开发实践具有理论指导意义。设计模式是开发经验的精炼和传承。设计模式在语法描述的层面上,对代码和代码之间的关系做出了精辟的描述和解释。这三个事务时程序开发的不可或缺的组成部分,就像是一个三角的三个顶点。当代码过一段时间,您就会发现其实做软件最重要的是管理学和方法论。毕竟计算机还是很老实的,一是一二是二。人,才是软件开发中的最大的不确定因素。方法论的理论指导作用贯穿了软件开发的各个里程碑。


Feedback
#1楼 2008-01-27 00:56 | deerchao
两大类仅能包含目前的"主流"语言而已,函数式语言List/Schema等等,动态语言Ruby/Python/JavaScript,面向并发的ErLang等都无法包含在内..
    
#2楼 2008-01-27 01:27 | 航天奇侠

如何写程序,比知道什么程序语法正确高级多了,这也是人与机器的分别。

    
#3楼 2008-01-27 02:55 | Jeffrey Zhao
话说现在没有Object Pascal了,已经正式叫做Delphi语言了,呵呵
    
#4楼 2008-01-27 08:51 | 布尔
思想就是慢慢的、不知不觉的落后的
    
#5楼 2008-01-27 08:53 | applethink()
编程主要还是类库的熟练和设计的思想,语言的障碍不大。
    
#6楼 2008-01-27 09:36 | carysun
我觉得
语言就是一种契约,一种规则
工具只是为了快捷方便
类库可以说是一些原语,面向过程的面向对象的都一样
这些不同的语言里都有,都不重要
重要的是解决方法的途径
    
#7楼 2008-01-27 09:44 | 金色海洋(jyk)
没有发现 basic 的身影。
    
#8楼 2008-01-27 14:12 | zzz [未注册用户]
还没有强调语言加类库的功能
如C++能做的,和Csharp能做的事有那些
如何选语言。。。。。。。。。。。。。
    
#9楼 [楼主]
2008-01-27 15:15 | Michael Lee
@zzz
其实不存在哪种语言和哪种类库配合才能做某些特定的事情的问题。

比如操作XML,如果您是使用C#,那么就会用到System.Xml命名空间下的相关类。但是这并不是说C++就不能做,因为MS早就推出了操作XML的COM组件。

    
#10楼 2008-01-27 16:20 | tmxkhd666 [未注册用户]
学习了.
说的也是那么个道道.
不过,有点好像没有说清楚.

    
#11楼 2008-01-27 16:49 | 怪怪
LZ关于语言的基本分类其实仅仅是一个子分支下的分类. 首先是函数式还是命令式, 这在模型上是根本性的不同. 另外现在很多语言都具有多种特征, 包括现在的C#和VB, 说他们仅仅是OO语言, 太贬低它们了..

其次C++并不属于典型的面向对象语言, 而是C++的一部分是面向对象的. 实际上C++在语言层面分为三部分: C/OO C++/Template C++, OO只是它的一小部分而已. 所以Meyers提到, 应该把C++视为一个语言联邦.

实际上划分语言的类型是没有什么价值的, 语言只是我们表达的方式. 只是由于发明者不同的设定, 选择不同的语言, 可能会有不同的限制. 这就使得选择产生了两方面因素: 什么语言更适合表达那些问题, 咱们从思维方式上更容易接受哪些限制. 但事实上, 现在我们选择语言, 往往是随大流, 这很可能是库在目标任务上是否够用产生的影响.

至于一门语言是不是难学, 我个人认为其实对于现在的环境来说, 由于有丰富的文档/使用指南/BUG列表, 库根本没什么影响. 库根本不用熟悉, 今天用, 今天上午掌握一下, 今天晚上忘掉即可. 如何使用不同风格的库, 库作者的偏好, 这些则是经验培养出来的.

相反, 语言本身的表达方式, 能走到多远, 能走得多好, 这才是语言中比较困难的地方. 不过相比LZ在最后提到的人的问题, 就都是小case了.
    
#12楼 2008-01-27 17:40 | 李洪超
楼主和大家的评论忽略了一个问题.从一种语言写的代码到可执行的程序中间有个编译过程.而对编译器,所输出程序的运行机制才是语言的基础.而楼主所说的语言只是语法而已.比如,说到C++为什么会有很多内存泄漏的问题,为什么C#就很少有这种情况.为什么C,C++在嵌入式系统应用很广,为什么Java,.Net在管理软件上占主导地位.这些都是和语言的编译机制,运行机制相关的.
所以说十天半个月能了解一种新语言的语法是可能的,要想熟练使用,不光是要学习相关类库,这些语言的深层问题也是必须要掌握的.
    
#13楼 [楼主]
2008-01-27 18:09 | Michael Lee
@李洪超
支持不支持垃圾收集的问题,其实是和代码质量和Run-Time相关的。.NET CLR环境下就根本没有内存泄漏而不是很少有。因为.NET的RunTime是支持了垃圾收集的。而在C/C++的RunTime中没有支持此功能而已。

您说的那些个"深层问题",我倒是觉得更多的是跟操作系统相关。^_^

    
#14楼 2008-01-28 09:21 | 巫云
我觉得只有2种:动态和静态。
    
#15楼 2008-01-28 09:51 | 李洪超
@Michael Lee
你所说的Runtime估计就是指DotNet中的CLR吧,C/C++有这种Runtime吗?没有吧,不然就不会出现这么多个版本的C++编译器了.
你也可以认为只有MSIL才是.Net平台的语言,经过编译变成二进制可执行文件.而C#,VB.net等只不过是MSIL之上的一种抽象.垃圾回收也是CLR实现的,和操作系统无关.我们也可以自己写个C++的垃圾回收类库,把new 和 delete都封装起来,如果做的彻底,也能够解决内存泄漏问题.
DotNet毫无疑问是平台独立的(尽管目前只在windows上应用).BTW,目前没有纯粹的dotnet环境,所以在任何实际项目中,内存泄漏仍然需要考虑的.

    
#16楼 [楼主]
2008-01-28 11:17 | Michael Lee
@李洪超
还是有CRT(C Runtim Library)的。不过CRT是一个文本的标准,每家厂商的实现都不一样,因而也会有很多的差别。
现在也有一些第三方公司提供库函数支持垃圾收集。只不过现在C++的标准里面没有把垃圾收集功能列入标准。

原因,我想是因为C++这个东西有点麻烦,适用平台很多(比如嵌入式系统),C++ 0x标准也是雷声大雨点儿小。要想都照顾到确实不是一件容易事儿。

在手持设备上实现虚拟机运行也是近些年的事儿,倒退个五、六年,这是不可想象的。
    
#17楼 2008-01-28 17:20 | 汪江涛 [未注册用户]
首先呢,学一门语言并不简单,类库倒是不难,比如C++,语言的元素是很丰富的,当然你要是把C++标准读了个遍说不定你学会它了。类库有什么难的?看着文档调用就行了呗,主要你得知道它是干什么的,你要调STL确不知道什么是模板类,要调Sytem.Threading确不知道线程是何物,要调3D图形库确不知道什么是法线、顶点、材质、贴图,那当然难了。其实最难的是业务,你把什么C#、Java、C++练得滚瓜烂熟,类库用的出神入化,让你写个财务软件,你不知道帐是怎么记的,白扯。
还好C++面向对象性还是很高的,要想使用面向对象的C++,很简单,不要写全局函数和变量,一切都用类封装,不要调C运行时库,调C++的运行时库。但语言的面向对象是一方面,设计的面向对象更重要。
语言应该还是有力量的,C/C++类库不也是C/C++写的吗?连主流操作系统都是C/C++写的,当然最初肯定用了汇编甚至机器码。

学语言不要太潦草,当到了一定程度时不要急着去实践,Java语法只掌握了一半就去写大型应用去了,认为这一半就够用了,当你知道另一半的时候你可能发现你10行代码有5行没用。

还有要知道语言是怎么实现的,机器是读不懂Java和C/C++的,就算C/C++编译成的可执行文件也不是简单的翻译,CPU没有函数参数的概念,也没有静态、全局、实例成员的概念,这些在机器代码里或Java的字节码、.net的IL里是怎么表达的?Java、.net的垃圾收集是如何实现的?所以不要以为语言没什么类库才是关键 -- 类库只是语言的一种应用,如果没有类库,你可怎么办啊?

有人用C/C++可能都不知道栈和堆的区别,用Java和.Net可能不知道引用计数这么个事,看起来没用,但不知道和知道是有区别的
    
#18楼 [楼主]
2008-01-28 17:55 | Michael Lee
汪兄所言极是!呵呵。
其实这些东东都是一通百通的。如果知道了堆和栈,那么理解.NET 的CTS和GC也就很简单了。
    
#19楼 2008-01-29 10:16 | 装配脑袋
其实语言应该主要分成命令式语言和函数式语言。这两种都有悠久的历史。命令式语言经历了很多发展阶段,最重要的是结构化。在结构化的编程语言出现之前命令式语言是缺乏结构的,也就是循环、跳转、分支都没有特定的语言结构。你说的pascal就正是结构化的代表,它引入了严格的过程调用,还有完善的循环和分支结构。OO是命令式语言的另一项发展里程碑,它引入了更大的抽象,实现了封装、继承和多态的概念,比以往更适应大型软件的设计开发。

然而函数式语言所带有的不更改语义,数学函数语义近年来越来越收到重视,因为它处理的方式不用考虑细节,为规则系统和集合操作提供了高度的抽象。如今主流的语言VB、C#都有不同程度的函数式语言成分。而Javascript, Python和Ruby等动态语言都有强大的函数式语法。

仅仅将语言分成“过程式”和“面向对象”,以及在此基础上讨论库的重要型是非常短见的。库非常重要,但库的好坏非常依赖于语言的抽象性。库的设计与程序设计有很大的不同,库是为了给程序员使用的,因此更注重语言方面的抽象。库的思想与语言的思想是完全不可分割的,绝不是什么语言“苍白无力”。如果语言苍白无力根本就不会有优秀的库出现。

学习不同方向的编程语言可以获得极大的启发,而绝不是注意一下大小写或者关键字拼法那么简单。建议LZ多见识见识一些自己没有用过的编程语言。总之,程序设计语言是计算机科学的一项伟大的发明,又是我们程序员做事情的根本,值得深入研究。
    
#20楼 2008-01-29 10:20 | 装配脑袋
@汪江涛
呵呵,.NET的对象引用是没有引用计数的。.NET GC用的分代收集,通过遍历活动对象关系图来标记所有不活动的对象。

来自:http://www.cnblogs.com/michaellee/archive/2008/01/26/1054627.html

分类: 编程语言 程序人生 修炼之道

上一篇:蔡学镛:2008编程语言走势解盘   下一篇:Ruby为什么会受程序员的欢迎?