设为首页 加入收藏

TOP

C 语言的前世今生(一)
2014-11-23 21:46:19 来源: 作者: 【 】 浏览:16
Tags:语言 今生

C 语言,从 1970 年代设计并实现之初,它就注定了带有强烈工程师文化的语言,而缺乏一些学术气息。它的许多细节设计,都带有强烈的实用化痕迹。C 语言因 UNIX 操作系统而生,是 UNIX 系统的母语。这导致在这个广泛应用的操作系统上开发,必须通过 C 语言的形式和系统进行交互。这不仅影响了 UNIX 一个平台上的软件,既而也影响了后来世界上最大的桌面系统 Windows ,以及越来越多的嵌入式平台。

由于大部分应用软件最终都需要和操作系统打交道,所以用来开发应用软件的语言,绝大部分也需要利用 C 语言完成和操作系统的通讯。这个世界上绝大部分流行的编程语言,都选择了用 C 语言来实现其编译器或解释器,以及基础部分的运行时库。无论 C 语言设计本身有何种缺憾,在今天,它已无可取代。

到了今天,大部分程序员不再需要逐个时间周期的去抠程序的性能。不需要刻意追求速度最快,最节省系统资源的软件。不需要写那些和系统内核紧密联系的程序。但 C 语言在此之外,依然有其重要的应用领域。我们可以把它作为对最终机器模型的高层次的统一抽象工具,而不必考虑机器环境的差异。经过 30 多年的发展,证明了 C 语言的确是对经典机器模型的最佳表述。仅仅通过增加了一个非常薄的胶合层就得到了一个清晰简洁的设计。正是这一点,使得 C 语言在计算机硬件高速发展的几十年中,一直生机勃勃。

我们在讨论 C 语言时,其实不仅仅涉及了 C 语言本身那用三十几个保留字构成的精简的控制结构和简约的语言特征。还包括了一套对 # 号打头的预处理部分(尤其是基于文本替换的宏处理),以及某些惯用的源代码组织方式(例如:所有的接口定义被定义在后缀为 h 的文件中,并通过预处理方式替换进源代码),和基本的程序库。

这几部分语言核心之外的部分相对独立。以至于使用 C 语言开发并不一定使用标准化的那些东西。C 语言对运行时环境的依赖是非常小的。

而编译预处理器又使得语言富有弹性,甚至可以写出违背 C 语言哲学的代码。著名的 IOCCC 大赛展示了许多常人无法理解的 C 代码。但实际上,C 语言主张代码清晰,表里如一。开发者和维护者都能很容易的预测每一行代码背后的行为。避免存在一些阴暗的角落藏着一些罕见的用法导致程序运行时出现诡异的行为。C 语言在发展过程中一直坚持着最小意外原则。而这一点,正是 C 语言的一个著名发展分支 C++ 所偏离的东西。

C 语言并不是绝对意义上最快的语言。但是它的效率非常好,在切合大部分机器模型并给出统一抽象的基础上,几乎没有其它语言做的更好了。这也是 C 语言哲学的一部分:在统一硬件抽象模型的基础上,尽可能的利用所在硬件环境的一切资源。有时候,C 语言程序员会走向某种极端。追求语言细节的优化,觉得某种代码的组织方式会比另一种方式更高效。但几乎总是错的。优化取决于对具体硬件的理解,以及对编译器如何翻译这些代码的了解。但这正是设计 C 语言想避免的东西。我们不必去争论在语句级上每行代码精确开销的优劣。

同时,C 语言的另一设计哲学就是让每行 C 代码尽量准确的对应相当数量的目标机器码。这使得程序员可以更为容易的理解程序的运行过程。让程序员脑海里可以实时地做一个源代码到最终控制流程的映射。基于这个思想,C 语言一直没有增加对结构进行运算的操作符(而 C++ 中把类或结构模拟成原生类型的做法相当普遍)。甚至于 inline 关键字也迟迟没有被标准化(inline 出现在 C99 标准中,而这个最新的 C 语言标准并没有被广泛接受),正是因为它某种程度破坏了这一点。

C 语言在坚持以上几点理念时,并非突出某个方面(比如追求性能),而是同时兼顾的。

C 语言并不是这个世界上唯一的编程语言,可惜的是,不是所有程序员都认识到了这点。对于把 C 语言作为自己唯一开发语言的程序员来说,很有必要开拓自己的眼界,这样反过来才能更为清晰的理解 C 语言的内在精神。并不是说,某某语言本身是用 C 语言来实现,那么 C 语言就可以以同样的方式,解决那种语言解决的问题(甚至更为高效)。一些 C 语言中的概念,到了另一种语言中,很可能用完全不同的方式展现出来。正如自然语言会影响人的思维方式一样,编程语言一样会影响人对某种算法的编码形式。在 C 里,我们总以为某些写法是自然而然的,但换了种语言却很可能并不尽然。

无论如何 C 语言的语法和设计影响了许多其它语言。最为彻底的是 C++ 。以及大多数程序员都能叫的出名字的一些流行语言:Java , PHP ,java script,Perl ,C#,D,Objective-C 等等。 这些给人造成一种错觉,新的语言取代了旧的,对老的语言做了改良和完善。最广泛传播的观点是,C++ 是 C 的一个超集,它能做所有 C 能做的所有事情,且能做的更好。持有这种观点的 C++ 程序员们甚至向把已有的各种 C 代码用 C++ 重新实现。但实际上,C 和 C++ 更应该被看成是相互平等的存在。C++ 更像是一种借用了几乎全部 C 语法(但还是有细微差异)的全新语言。它们在很多方面都有设计理念上的差异。C++ 企图完全兼容 C 的语法却不想完全继承 C 语言的理念,这使它背负了巨大的包袱。而 C 的另一个继任者:Objective-C ,抛弃了一些东西,则显得清爽一些。

回顾 C++ 出现的时代背景在于把面向对象当成解决复杂问题的“银弹”的年代。这使得 C++ 在发明之初,迅速的占领了大量原本是 C 语言的市场,甚至被看成是 C 语言的替代品。但 C++ 的拥趸们并没有等到这一天。历史证明,面向对象也不是“银弹”、最近十年,C++ 的粉丝们从 C++ 语言的犄角旮旯里挖掘出来的各种武器,让 C++ 语言变成了包含多种编程范式的巨无霸。却并没有让解决问题变得更容易。这并不完全是语言的问题,可能有很大程度上是面向对象等开发方法本身的问题。这也证明了 C 语言保持自身的简洁正是其生机昂然的源泉。

和浩如烟海的 C++ 书籍相比较。如果你已经是程序员,但还不了解 C 语言的话。学习 C 语言,只需要读一本书,而这本书没有第二选择,就是经典的《The C Programming Language》(K&R)。薄薄的一本就讲透了语言的方方面面。可惜的是,C 语言过于注重对机器模型的抽象,并不适合用来程序员入门。尤其是在国内的教材市场,充斥着大量糟糕的 C 语言教材。在这些拙劣的教材中,甚至把开发工具(比如特定的 C 语言开发集成环境)和特定的硬件环境(甚至是过时的 8086 内存模型)与语言教学混为一谈。

对于 C 语言不是母语的程序员来说,有充分的理由去学习一下 C 语言。那是低投入,高产出的。它会使你学会在硬件层次上思考问题(这或许对你是一个新的思维角度)。而且 C 语言已经非常稳定,不会再有(它本身也不希望有)大的变化,不用担心学到的知识会过时。C 语言在 1990 年制订出一个现在通行的标准( C90 )以来,在 C 的主流开发社区中几乎没有变过了。虽然,从 1999 年开始,C 语言委员会几经修订 C 语言的新标准( C99 ),但似乎并不被广泛接受。虽然有很大程度上,这是源于世界上最大的 C/C++ 商业编译器提供商微软对其不感兴趣。可在开源界,即使有 GNU C 对 C 语言新标准的不断推动,那些实际用 C 语言做开发的大佬们还是纷纷表示,新的标准还不是很成熟。新的特性也不是特别有必要。

笔者用 C99 开发有一些年头,但也只使用了其中一个子集,不太敢在正式项目中完全推广。至于 C 语言近年来的发展,我个人比较欣赏苹果公司对 C 语言添加的 blocks 扩展以用来实现 closure 。但并不看好这些

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇经典算法研究系列:十三、通过浙.. 下一篇漫谈C语言及如何学习C语言

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: