目录
1.1 C语言的历史
1.1.1 起源
1.1.2标准化
1.1.3 基于C的语言
1.2C语言的优缺点
1.2.1C语言的优点
1.2.2C语言的缺点
1.2.3高效的使用C语言
如果有人说“我想要一种语言,只需要对它说我要干什么就行”,给他一支棒棒糖好了
1.1 C语言的历史
1.1.1 起源
????????C语言是贝尔实验室的Ken Thompson、Dennis Ritchie等人开发的UNIX操作系统的“副产品”,UNIX操作系统是用汇编语言写的,但是用汇编语言编写的程序往往难以调试和改进。
????????Ken Thompson意识到需要用一种更加高级的编程语言来完成UNIX系统未来的开发,于是他设计了一种小型的B语言。
? ? ? ? 随后为了满足实际需求,Dennis Ritchie开始着手开发B语言的升级版,最初他将其命名为NB语言(New B)但是该语言在后续的开发中越来越偏离B语言,于是他将其改名为C语言。
? ? ? ? 到了1973年,C语言已经足够稳定,可以用来重新编写UNIX系统了,改用C语言编写程序有一个非常重要的好处:可移植性。只要为贝尔实验室的其他计算机编写C语言编译器,他们的团队就能让UNIX系统也运行在那些机器上。
1.1.2标准化
????????随着 C 语言的迅速普及,一系列问题接踵而至。编写新的 C 语言编译器的程序员都用Brian
Kernighan 和 Dennis Ritchie 合作编写的《C 程序设计语言》一书(也称K&R 或“白皮书”)
作为参考。
???????
????????但遗憾的是,K&R 对一些语言特性的描述非常模糊,以至于不同的编译器常常会对这些特性
做出不同的处理。而且,K&R 也没有对属于 C 语言的特性和属于 UNIX 系统的特性进行明确的区
分。更糟糕的是,K&R 出版以后 C 语言仍在不断变化,增加了新特性并且去除了一些旧的特性。
很快,C 语言需要一个全面、准确的最新描述开始成为共识。如果没有这样一种标准,就会出现各
种“方言”,这势必威胁到 C 语言的主要优势——程序的可移植性。
??????????1983 年,在美国国家标准学会(ANSI)的推动下,美国开始制订本国的 C 语言标准。经
过多次修订,C语言标准于1988年完成并在1989年12月正式通过,成为ANSI标准X3.159-1989。
1990 年,国际标准化组织(ISO)通过了此项标准,将其作为 ISO/IEC 9899:1990 国际标准①。
我们把这一 C 语言版本称为 C89 或 C90,以区别于原始的 C 语言版本(经典 C)。
????????1995 年,C 语言发生了一些改变(相关描述参见 Amendment 1 文档)。1999 年通过的
ISO/IEC9899:1999 新标准中包含了一些更重要的改变,这一标准所描述的语言通常称为 C99。由
于存在两种标准,以前用于描述 C89 的 ANSI C、ANSI/ISO C 和 ISO C 等术语现在就有了二义
性。
????????C 语言的最近两次改变分别发生在 2011 年和 2018 年。国际标准化组织在 2011 年通过的 C
语言标准是 ISO/IEC 9899:2011,这一标准所描述的 C 语言通常称为 C11;在 2018 年通过的 C
语言标准是 ISO/IEC 9899:2018,这一标准所描述的 C 语言通常称为 C18。
????????从 C99 到 C11 再到 C18 的变化,没有从 C89 到 C99 那么显著。尤其是从 C11 到 C18 的变
化,仅限于技术修正和澄清,总体上没有显著的改变,也没有引入新的语言特性。
1.1.3 基于C的语言
????????C 语言对现代编程语言有着巨大的影响,许多现代编程语言都借鉴了大量 C 语言的特性。
在众多基于 C 的语言中,以下几种非常具有代表性:
- C++:包括了所有 C 特性,但增加了类和其他特性以支持面向对象编程。
- Java:基于 C++,因此也继承了 C 的许多特性。
- C#:由 C++和 Java 发展起来的一种较新的语言。
- Perl:最初是一种非常简单的脚本语言,在发展过程中采用了 C 的许多特性?
????????考虑到这些新语言的普及程度,人们自然会问:“C 语言还值得学习吗?”,我想答案是肯定
的,原因如下:
- 学习 C 有助于更好地理解 C++、Java、C#、Perl 以及其他基于 C 的语言的特性,而一开始就学习其他语言的程序员往往不能很好地掌握继承自 C 语言的基本特性;
- 目前仍有许多 C 程序,我们需要读懂并维护这些代码;
- C 语言仍然广泛用于新软件开发,特别是在内存或处理能力受限的情况下以及需要使用 C 语言简单特性的地方。
1.2C语言的优缺点
1.2.1C语言的优点
????????高效性是 C 语言与生俱来的优点之一。发明 C 语言就是为了编写那些以往由汇编语言编写的
应用程序,所以对 C 语言来说,能够在有限的内存空间里快速运行就显得至关重要了。
- 可移植:虽然程序的可移植性并不是 C 语言的主要目标,但它还是成了 C 语言的优点之一。当程序必须在多种机型(从个人计算机到超级计算机)上运行时,常常会用 C 语言来编写。C 程序具有可移植性的一个原因是该语言没有分裂成不兼容的多种分支。另一个原因是 C语言编译器规模小且容易编写,这使得它们得以广泛应用。
- 功能强大:C 语言拥有一个庞大的数据类型和运算符集合,这个集合使得 C 语言具有强大的表达能力,往往寥寥几行代码就可以实现许多功能。
- 灵活:虽然 C语言最初设计是为了系统编程,但是没有固有的约束将它限制在此范围内。C 语言现在可以用于编写从嵌入式系统到商业数据处理的各种应用程序。此外,C 语言在其特性使用上的限制非常少。在其他语言中认定为非法的操作在 C 语言中往往是允许的。
- 标准库:C 语言的一个突出优点就是它具有标准库,该标准库包含了数百个可以用于输入/输出、字符串处理、存储分配以及其他实用操作的函数。
- 与 UNIX 系统的集成:C 语言在与 UNIX 系统(包括广为人知的 Linux)结合方面特别强大。事实上,一些 UNIX 工具甚至假定用户是了解 C 语言的。
1.2.2C语言的缺点
C 语言的缺点和它的许多优点是同源的,均来自 C 语言与机器的紧密结合:
- C 程序更容易隐藏错误:C 语言的灵活性使得用它编程出错的概率较高。在用其他语言编程时可以发现的错误,C 语言编译器却无法检查出来。从这方面来说,C 语言与汇编语言极为相似,后者直到程序运行时才能检查到大多数错误。更糟的是,C 语言还包含大量不易觉察的隐患。在后续的章节中我们将看到,一个额外的分号可能导致无限循环,遗漏一个&可能引发程序崩溃。
- C 程序可能会难以理解:虽然大多数衡量标准认为 C 语言是一种小型语言,但是它有许多其他通用语言没有的特性(并且常常被误解)。这些特性可以用多种方式结合使用,其中的一些结合方式尽管编程者心知肚明,但是其他人恐怕难以理解。另一个问题就是C 程序简洁的本质。C 语言产生的时候正是人机交互最为单调乏味的时期,因此设计者特意使 C 语言简洁以便将输入和编辑程序的用时减到最少。C 语言的灵活性也可能是一个负面因素,过于聪明的程序员甚至可以编写出除了他们自己几乎没人可以读得懂的程序。
- C 程序可能会难以修改:如果在设计中没有考虑维护的问题,那么用 C 语言编写的大规模程序将很难修改。现代的编程语言通常都会提供“类”和“包”之类的语言特性,这样的特性可以把大的程序分解成许多更容易管理的模块。遗憾的是,C 语言恰恰缺少这样的特性。
1.2.3高效的使用C语言
????????高效地使用 C 语言要求在利用 C 语言优点的同时要避免它的缺点。下面是一些建议:
- 学习如何规避 C 语言的缺陷:尝试去参考 Andrew Koenig 的《C 陷阱与缺陷》一书。现代编译器可以检查到常见的缺陷并且发出警告,但是没有一个编译器可以发现全部缺陷。
- 使用软件工具使程序更加可靠:C 程序员是众多软件工具的制造者(和使用者)。lint 是最著名的 C 语言工具之一,一般由 UNIX 系统提供。与大多数 C 语言编译器相比,lint 可以对程序进行更加广泛的错误分析。如果可以得到 lint(或某个类似的程序),那么使用它应该是个好主意。另一个有益的工具是调试工具。由于 C 语言的本质,许多错误无法被 C 编译器查出。这些错误会以运行时错误或不正确输出的形式表现出来。因此在实践中,C 程序员必须能够很好地使用调试工具。
- 利用现有的代码库:使用 C 语言的一个好处是,许多人也在使用 C。把别人编写好的代码用于自己的程序是一个非常好的主意。C 代码经常被打包成库(函数的集合)。获取适当的库既可以大大减少错误,也可以免去相当多的编程工作。用于常见任务(包括用户界面开发、图形学、通信、数据库管理以及网络等)的库很容易获得。有些库是公用的,有些是开源的,有些则是作为商品销售的。
- 采用一套切合实际的编码规范:编码规范是一套设计风格准则,即使语言本身没有强制要求,程序员也会遵守。精心选择的规范可以使程序更加统一,并且易于阅读和修改。使用任何一种编程语言时,规范都很重要,C 语言尤其如此。正如前面所说的,C 语言本身具有高度的灵活性,这使得程序员编写的代码可能会难以理解。选用哪种编码规范并不重要,重要的是必须采纳某些规范并且坚持使用它们。
- 避免“投机取巧”和极度复杂的代码:C 语言鼓励使用编程技巧。用 C 语言完成某项指定任务时通常会有多种解决途径,程序员经常会尝试选择最简洁的方式。但是,千万不要没有节制,因为最简略的解决方式往往也是最难以理解的。
- 紧贴标准:大多数 C 编译器提供不属于 C89、C99 或者 C1X 标准的特性和库函数。为了程序的可移植性,若非确有必要,最好避免使用这些特性和库函数。
~over~