C 语言风格流变史

2008-02-23 05:29:12来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

标题:C 语言风格流变史
作者:王咏刚
时间:2003年11月

  程式代码也有风格,这算不得什么新鲜事。早在20世纪80年代, C语言程式员就必须在K&R风格和ANSI风格之间择善而从。但平心而论,我确实没有见过哪一种语言能像C 这样,在代码风格方面表现得如此诡谲和难以捉摸:谁也说不清C 代码究竟能衍生出多少种迥异的风格,但我知道,有许多C 初学者在面对不同风格的C 代码时,经常会误以为自己看到的是好几种完全不同的编程语言——仅此一点就足以提醒我们,研究和廓清C 语言风格的演化和发展规律已是当务之急了。

  和文体学家们研究历朝历代文体变迁的工作相仿,研究C 语言风格的流变史也没有什么捷径可走。我们只能依据刘勰在《文心雕龙》中提倡的“原始以表末”[1]的研究方法,循着历史的脉络,推求代码风格的来源,探寻风格演化的内因,并借以阐明技术发展的趋势和规律。

1. 带类的C——对C语言风格的因袭

  在1983年12月Bjarne Stroustrup采纳Rick Mascitti的建议,将其发明的新语言命名为“C ”之前,人们一直用“带类的C(C with Classes)”来称呼这种脱胎于C语言的,带有数据抽象机制的“方言”。虽然带类的C在本质上仅仅是一种能够被预处理程式Cpre转换为传统C语言代码(这类似于我们在Oracle中见到的Pro*C语言的预处理过程)的扩展性语言,但他的确在风格上奠定了后来任何C 代码的基础。

class stack {
char s[SIZE];
char* min;
char* top;
char* max;
void new();
public:
void push(char);
char pop();
};
  这段“带类的C”代码录自Stroustrup所著的《C 语言的设计和演化》。代码中的new()其实是类stack的构造函数,这和后来的C 语言有很大的不同。

  显而易见,带类的C在风格上几乎完整地承袭了C语言的衣钵。代码中的声明语句看上去和C语言一模相同,class的结构也和C语言中struct的结构大致相仿,这些迹象反映出C 语言来源于C又尽量和C保持兼容的设计思想——这种设计思想既为C 的迅速普及提供了便利(C 语言的顺利推广显然得益于C语言已有的庞大用户群),也在C 的语言风格中深深地烙上了C语言的印记,以至于在若干年后,当C 语言已基本具备了“单独人格”的时候,Stroustrup还不得不时常提醒人们要尽量抛开C语言的思维方式。

  另一方面,Stroustrup从Simula语言借用的类、派生、访问控制等面向对象概念在带类的C中牢牢地扎下了根。据Stroustrup介绍,他为C语言引入面向对象机制的本意在于寻找一种“合适的工具”[2],以便实现分布式系统或解决类似的复杂问题。但无论怎样,Stroustrup将C的高效和Simula的优雅捆绑在一起的做法都在事实上为C 语言埋下了“双重性格”的种子——很难说这不是C 语言风格多样化的直接诱因。

2. I/O流——C 的新形象

  假如说C 语言的生身父母分别是C语言和Simula语言的话,那么,1984年出现的,借助操作符重载实现的I/O流技术就是C 这个幼童甩开父母的庇护,向新的代码风格迈出的第一步了。

ostream& operator<<(ostream&s, const complex& z)
{
return s << '(' << z.real()
<< ',' << z.imag() << ')';
}
  上面几行代码来自Stroustrup所著《C 程式设计语言》中的示例程式。注意那一行由“<<”连接的代码,I/O流、变量、字符常量在代码中被巧妙地串联在一起。从技术角度看,这种全新语法的引入弥补了C语言中printf()函数族缺乏类型安全机制和扩展能力的弱点。从代码风格上说,“<<”等通俗易懂的运算符大大改变了程式员对C 语言的第一印象。我自己第一次接触C I/O流库时,就曾清楚地感觉到,一个试图摆脱C语言风格束缚的C 精灵正顺着“<<”和“>>”组成的溪水“流淌”而来——这种行云流水般的代码风格在十几年前就已显示出了C 语言在塑造新形象、引进新观念方面的决心和勇气。

3. OWL和MFC——窗口环境下的风格变异

  20世纪80年代末到90年代初,X Window、Mac OS、Windows等窗口环境的先后出现为程式设计提出了新的课题,而C 语言兼顾面向对象和传统研发方法的特性无疑使其成为了窗口环境下编程语言的最好选择。一批基于C 语言的窗口框架不但在商业上取得了成功,也在很大程度上改变了C 语言本身的风格特点。

  最早在窗口研发中赢得大多数程式员青睐的C 框架是Borland公司于1992年内置在Borland C 3.1中的OWL(Object Windows Library)框架库。下面这段代码取自Borland C 3.1的示例程式:

class TGDIDemoWindow : public TMDIFrame
{
public:
TGDIDemoWindow( LPSTR ATitle, LPSTR MenuName )
: TMDIFrame(ATitle, MenuName) {};
virtual void SetupWindow();
virtual void ArtyDemo( TMessage& ) =
[CM_FIRST ArtyDemoID];
virtual void Quit( TMessage& ) =
[CM_FIRST QuitID];
virtual void WMTimer( TMessage& ) =
[WM_FIRST WM_TIMER];
virtual void WMDestroy( TMessage& ) =
[WM_FIRST WM_DESTROY];
};
  为了解决窗口编程中最关键的消息映射问题,OWL的设计者为C 语言的成员函数引入了“=[…]”的古怪语法,这是许多用过Borland C 的程式员至今都无法忘怀的一种语言风格。我承认,Borland公司在C 语言的发展初期为我们提供了最好的编译器和最出色的集成研发环境(IDE),但Borland通过OWL框架为C 引入的另类语言风格的确让人不敢恭维(客观地讲,这笔账也不应全算在Borland头上,因为OWL的前身是Borland从White Water公司购买的框架代码)。

  就在Borland C 3.1统治市场两年以后,Microsoft凭借其当仁不让的霸气和著名的Visual C 系列产品逐渐夺回了Windows研发工具市场的主导权。和Borland不同的是,Visual C 中的MFC(Microsoft Foundation Class)框架库没有向OWL那样肆意篡改C 的语法,而是采用了下面这样的方式来实现消息映射(代码取自MSDN示例程式):

// Example for BEGIN_MESSAGE_MAP
BEGIN_MESSAGE_MAP( CMyWindow, CFrameWnd )

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 怎样将C语言声明转换为VB声明

下一篇: 关于子程式的最好长