编程语言的层次观点——兼谈C++的剪裁方案

    几个月前,我在CSDN上发表了一篇短文,叫《风格的选择》。在那篇文章里,我提出一个观点:面对不同应用领域和环境,C++的开发者应该主动剪裁语言,选择最合适自己领域的C++子集进行具体开发。这是从我的实际工作中总结出来的想法,始终只是一种经验主义的东西。我觉得这是正确的选择,但是如果有人问我为什么,我自己也深感困惑,无法回答。最近一段时间,因为工作方向的调整,我逐渐偏向低层技术,对于计算机体系结构、操作系统等以前不太注意的领域投入了相当大的精力学习,逐渐对上面那个曾经令我困惑的问题有了一些想法,并且对我之前的观点有了进一步的扩展。我想在这里再次拿出来,与大家探讨。

    首先要说明的一点是,语言绝对不是一个无关紧要的问题。很多人喜欢引述的一句话是:编程语言只是工具,关键是背后的算法和思想。这种说法起源于某些讲授算法的资料。应该说,对于算法描述来说,语言之间的差异是无关紧要的,但是现代的编程语言并不仅仅是用来表述算法的工具,更重要的是作为构件单元来构造系统。语言的能力、表达风格、思维方式、特性以及习惯用法将在很大程度上决定系统的架构、功能和基本特点,决定人们设计和生产软件的方式。因此,我们才有必要始终对编程语言的发展报以巨大的关注。按照我一个朋友的说法,编程语言始终是计算机领域中最本质的东西之一,特别是在计算机工程(而不是科学)领域中,“用什么形式来控制机器”始终是一个核心问题。

    说实在的,这个话题很大,我也想到了很多东西。但是我没有足够的时间来详细解释,更没有时间精心组织这些观点。所以,在这篇文章里,我只是简单地罗列和阐述我的基本观点。我相信真正对这个话题感兴趣的朋友不会介意这样的形式。李泽厚曾经说,他不喜欢德国式的写作方法,写了厚厚的两三卷,上百万字,还只是一个“导论”,他喜欢简洁明了的“提纲”。我发现,当时间不够用的时候,李先生的观点是颇有诱惑力的。

【基本观点】
1. 编程语言与软件系统一样,处于不同层次。层次越高,对人越友好,控制机器的能力越差;层次越低,控制机器的能力越强。选择开发语言时,根据需要解决的问题选择合适的语言层次,是非常必要的。下面是我对于常见语言所划分的层次:

    低层语言:汇编,C,Forth  

    应用场合:控制系统、操作系统、虚拟机、解释器、高速数据处理、核心计算引擎

    中层语言:Java, C#, VB.NET, Delphi(Object Pascal),  Eiffel, Oberon-2, ...

     应用场合:大部分通用和专用软件
    

    高层语言:Perl, Python, Ruby, HTML, SQL,   JavaScript, ShellScript, VB, ...

    应用场合:主要面向专用软件的开发

    通用语言:Ada, C++                                  应用场合:所有

    专用语言:COBOL, Fortran                            应用场合:大型机,商务和数值运算

    如果在开发时错误选择了编程语言,则至少是不经济的、复杂的,严重的话会导致整个项目的彻底失利。


2. 什么是低层语言?通常对这个问题有很多不同的答案。我个人对于低层语言有以下一些描述:
   1) 直接反映机器行为,而不是人的行为;
   2) 强调对机器的控制能力,兵器能够利用这种控制能力最大限度优化操作;
   3) 存在到机器语言的清晰映射关系;
   4) 能够满足系统编程工作的需求。

    所谓系统编程,在我看来,就是值得为优化性能(这里不仅仅指速度性能)而付出高昂代价的编程工作。有个德国人说得更加直接了当:“所谓系统编程,就是那些CPU时间比程序员的时间更重要的工作。” 显然这不是一个很学术的描述,甚至也不是一个让人感到很愉快的说法,但是确实是一个很好的描述。
   
    在低层语言中,C是一种值得大声赞美的语言。C是一个如此了不起的杰作,它以高级语言的形式,构造了一个“可移植的优化汇编代码产生器”,高效、灵活而且完备。然而,有太多的人和组织把大量的精力用来将C变成一种更高层的语言,比如以各种奇怪的宏给它加入面向对象的特性。虽然这被证明是可能的,但从来没有得到广泛地应用,原因很简单——这脱离了C所处的层次,既不经济,也不直观。


3. 中层语言是一般程序员的最佳选择。中层语言可能是我自己“造”出来的一个词汇。我觉得当前最流行的几种语言都属于中层语言。它们的共同特点是,既提供了比较强的控制能力,又强调了对程序员的友好。生产效率较之低层语言有几倍甚至十倍的提高。一般来说,中级语言遵循某一种编程思想,提供了比较强大但是简单的抽象机制,通过完备的库提供高层和低层的控制能力。在可以遇见的将来,中级语言仍将继续是最受欢迎的开发语言。中级语言有其局限性,一方面它对机器的控制能力有限,无法进行最精细的优化。另一方面其背后的指导思想比较单纯,因此需要做出很多妥协才能达成完备性。此外,中级语言通常变化很快,不太稳定。

    中级语言中,Java和C#等运行在用C/C++写成的虚拟机上,Eiffel编译产生C语言代码,这形象地表明它们并非直接面向硬件的低层语言。同时,这些语言又被用来构造基础类库 (Foundation library),运行时环境甚至控制系统这些传统上被认为是“系统编程”的工作,所以它们在生产力与控制力之间取得了良好的折中。对于普通程序员来说,是最好的学习选择。而对于一般项目来说,也是优选的开发工具。

4. 通用语言(general purpose)。C++, Ada等通用语言,其实是试图摆脱上述的语言分层,希望以单一语言适应各层需求,面对各个应用领域。因此,它们必须立足某一个层次,通过某种形式的抽象提高或者降低自己的层次。比如,C++立足于低层语言C,通过类、模板、继承等机制提高自己的层次;而Ada,立足于“基于对象”这样比较高层的思想,通过各种package来提供底层控制能力。可以说,某种形式的抽象,是提高(和降低)语言层次的唯一手段。然而,抽象是要付出代价的,抽象能力的增强,要么伴以控制能力的减弱,要么伴以复杂度的剧增。Ada和C++不约而同地选择了强大的抽象能力和控制能力,而构造了复杂无比的语言系统。

5. 一旦提供良好的语言互操作性,各种不同层次语言的有效结合将是构造系统最经济、最有效的方式。相比之下,使用某一种通用语言构造整个系统将是非常不经济的选择。也就是说,让各种语言产生的代码在二进制层面上互相合作,比让程序员在不同的语言层次之间跳跃,要更加经济可靠。

6. 我们可以把一种通用语言看成是纵跨若干层次的几个语言子集的统一体。这也就使得对语言的剪裁在客观上成为合理的行为,同时也是非常困难的过程。因为由几个语言子集组合而成,所以我们可能剪裁语言,以适应各层次的需要。而由于是统一体,这种剪裁难度很大。

7. C++目前作为一种系统语言(也就是低级语言)是完备的,但是作为中高级语言,其支持库、语言机制还有不少缺陷(比如缺乏统一的对象级回调机制)。这给那些希望把C++当成高级语言来使用的人带来很大的麻烦。在这些问题没有解决之前,C++最佳的应用领域仍然是系统开发中——也就是说,把纵跨各层的通用语言C++当成一种低级语言来运用,只在绝对合适的时候恰到好处地运用较高层的机制。

    根据P. J. Plauger的论述,对于C++,大致存在从小到大若干个剪裁方案,图示如下:

                  ANSI C
                    |
                    |
                    | 加入引用、重载等简单扩展
                    |
                    |
                  A better C
                    |
                    |
                    | 加入非虚成员函数、具体类
                    |
                    |
                  Object-based C++
                    //
                   /  /
  加入模板  /    / 加入单继承和多态
                 /      /
                /        /
Object-based    Embedded C++  
Template C++}
               /          /
                /        /
                 /      /
                  /    /
                   /  /
                    //
            Embedded Template C++
                    |
                    | 加入多继承、虚基类、异常
                    |
                    |
                ANSI C++

    希望这个图能够对面对实际领域的C++程序员能有帮助。对我自己而言,Better C没有吸引力,我不如直接用移植性更好的C本身。Object-Based C++提供了类和封装,但是提高有限,用C语言也可以很容易的达到相同效果。Embedded C++是日本人制定的一个标准,基本上就是1987年的C++,可用性很高。文档中并没有Object-based Template C++这种说法,只是理论上存在这种可能,即完全不使用继承、多态、异常,只用具体类和模板(STL)进行开发,这与Herb Sutter在1998年之前所倡导的编程风格非常接近。Embedded Template C++是一个非正式的称呼,主要由Green Hill公司、Metrowerk(Code Warrier)等公司维护,最适合嵌入式应用软件的开发。微软的Embedded Visual C++ 3.0就是一个优秀的Embedded Template C++实现,不过它支持多继承和虚基类,以支持COM开发。最后当然就是ANSI C++了。现在嵌入式开发工具的制造商都以全面支持ANSI C++为荣,但是我觉得嵌入式系统的开发人员很长时间(也许永远)都不会需要用到ANSI C++的全集。

   

   
   

  • 2
    点赞
  • 3
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

Visual C++范例大全 本书全部源码打包(1~17章)共406个实例 光盘说明 1.本书代码运行环境 1~17章 Visual C++ 6.0 2.本书所附光盘实例源码 第1章 实例001——实现C++多重继承 实例002——使用虚函数实现运行时多态 实例003——操作符重载实现编译多态(复数加法运算) 实例004——使用函数模板实现不同数据类型极值函数 实例005——使用C++实现格式化数据IO 实例006——实现数字金额中文大写转换 实例007——将十进制数转换为二进制输出 实例008——产生随机数 实例009——实现排序操作 实例010——使用Windows API创建程序窗口 实例011——使用AppWizard创建基于文档视图结构MFC应用程序框架 实例012——使用AppWizard建立对话框应用程序框架 实例013——实现查找、替换字符串 实例014——根据指定字符分割字符串 实例015——格式化字符串 实例016——CString字符串类型转换 实例017——获取当前日期、时间并格式化输出 实例018——计算某日为星期几 实例019——计算两个时间点时间间隔 实例020——使用CStringArray类创建和使用字符串数组 实例021——使用CPtrList类创建和使用链表 第2章 实例022——基本键盘操作——判断按键消息 实例023——在普通视图窗口中实现键盘字符输入 实例024——创建和使用键盘插入符 实例025——使用程序模拟键盘输入 实例026——在对话框中实现键盘消息响应 实例027——向其他应用程序(记事本)中发送键盘消息 实例028——基本鼠标操作——判断鼠标消息 实例029——创建并设置鼠标光标 实例030——在对话框中定义光标热区 实例031——创建和使用鼠标提示框 实例032——在视图窗口实现捕捉鼠标 实例033——限制鼠标作用区域在客户窗口 实例034——使用程序模拟鼠标动作 实例035——创建和使用自定义消息 实例036——使用命令范围消息处理函数 实例037——使用定时器实时显示当前时间 实例038——使用定时器显示毫秒级时间 第3章 实例039——创建和使用下压按钮、单选框和复选框 实例040——实现位图按钮,设定控件文本字体 实例041——实现超链接风格按钮 实例042——实现动画按钮 实例043——使用单行、多行编辑框输入显示文本 实例044——只允许输入字母,并转换为大写编辑框 实例045——单行编辑控件输入回车后,不响应默认控件处理消息 实例046——设置编辑框控件背景、文本颜色 实例047——创建完全只读(没有输入焦点,不能选择)编辑框 实例048——实现只能输入小数编辑框控件 实例049——使用Rich Edit编辑框格式化显示文本 实例050——设定静态文本框背景色和文本颜色 实例051——使用Picture控件实现分隔线 实例052——使用静态文本控件显示图标和位图 实例053——在静态文本控件上进行绘图 实例054——创建显示数字钟静态文本框 实例055——创建超链接风格静态控件 实例056——添加删除列表框数据 实例057——创建带有复选框列表框和可拖放列表项列表框 实例058——实现选中项缩进列表框 实例059——创建带有智能水平滚动条列表框 实例060——添加和获取组合框列表项 实例061——使用扩展组合框使组合框选项带有图标 实例062——在组合框下拉列表框中实现自动选择 实例063——创建颜色选择下拉组合框 实例064——使用滑块控件和调节钮控件设置选择范围 实例065——使用滚动条和进度条进行范围设置 实例066——创建带有文本指示自定义进度条 实例067——动态创建和删除编辑控件 实例068——在视图中创建和使用控件 第4章 实例069——使用列表控件添加和选择数据项 实例070——动态设置列表控件不同显示方式 实例071——实现列表控件扩展风格(拖放、整栏选择和显示网格) 实例072——使用树形控件显示数据 实例073——动态添加、删除树形控件节点,获取树形控件选中项 实例074——在树形控件中使用背景位图 实例075——创建可编辑节点树形控件 实例076——使用树形控件和列表控件显示系统资源列表 实例077——在程序中使用月历控件 实例07
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值