1 介绍
计算机系统是由硬件和系统软件组成的
20 世纪 60 年代是大型、复杂操作系统盛行的年代
比如 IBM 的 OS/360 和 Honeywell 的 Multics 系统
OS/360 是历史上最成功的软件项目之一
而 Multics 虽然持续存在了多年,却从来没有被广泛应用过
贝尔实验室曾经是 Multics 项目的最初参与者
但是因为考虑到该项目的复杂性和缺乏进展而于 1969 年退出
鉴于 Multics 项目不愉快的经历,一群贝尔实验室的研究人员
—— Ken Thompson、Dennis Ritchie、Doug Mcllroy 和 Joe Ossanna
从 1969 年开始在 DEC PDP-7 计算机上完全用机器语言编写了一个简单得多的操作系统
这个新系统中的很多思想,比如层次文件系统、作为用户级进程的 shell 概念,都是来自于 Multics
只不过在一个更小、更简单的程序包里实现
1970 年,Brian Kernighan 给新系统命名为 “ Unix ”
这也是一个双关语,暗指 “ Multics ” 的复杂性
1973 年用 C 重新编写其内核,1974 年,Unix 开始正式对外发布
贝尔实验室以慷慨的条件向学校提供源代码
所以 Unix 在大专院校里获得了很多支持并得以持续发展
最有影响的工作发生在 20 世纪 70 年代晚期到 80 年代早期
在美国加州大学伯克利分校,研究人员在一系列发布版本中增加了虚拟内存和 Internet 协议
称为 Unix 4.xBSD(Berkeley Software Distribution)
与此同时,贝尔实验室也在发布自己的版本,称为 System V Unix
其它厂商的版本,比如 Sun Microsystems 的 Solaris 系统
则是从这些原始的 BSD 和 System V 版本中衍生而来
20 世纪 80 年代中期,Unix 厂商试图通过加入新的、往往不兼容的特性来使它们的程序与众不同,麻烦也就随之而来了
为了阻止这种趋势,IEEE(电气和电子工程师协会)开始努力标准化 Unix 的开发
后来由 Richard Stallman 命名为 “ Posix ”
结果就得到了一系列的标准,称作 Posix 标准
这套标准涵盖了很多方面,比如 Unix 系统调用的 C 语言接口、shell 程序和工具、线程及网络编程
最近,一个被称为 “ 标准 Unix 规范 ” 的独立标准化工作已经与 Posix 一起创建了统一的 Unix 系统标准
这些标准化工作结果是 Unix 版本之间的差异已经基本消失
C 程序设计语言最早是由 Dennis Ritchie 于 1973 年设计并实现的
最初是为 UNIX 操作系统设计的,在 UNIX 系统上开发,在 DEC PDP-11 计算机上实现
UNIX 操作系统本身、C 编译器和几乎所有的 UNIX 应用程序都是用 C 话言编写的
但是,C 语言不受限于任何特定的机器或操作系统,使用它可以很容易地编写出不经修改就可以运行在所有支持 C 语言的机器上的程序
一些适用于其它机器的编译器产品可以将 C 语言编译为可以运行在非 UNIX 系统上运行的机器语言
如:IBM System/370、 Honeywell 6000 和 Interdata 8/32 等
1970 年,贝尔实验室的 Ken Thompson 在 BCPL 的基础上改进出了 B 语言,用于开发 UNIX
Ken Thompson 在 DEC PDP-7 计算机上开发的 B 语言
3 年后的 1973 年,贝尔实验室的 Dennis Ritchie 将 B 语言进一步改进,并且取了 BCPL 中的第二个字母将其命名为 C 语言
开发完成后再用 C 语言重写了 UNIX 系统内核
这也是 C 语言最初的目标,即让程序员可以使用一种更容易理解的语言来编写系统程序
BCPL 和 B 语言都是 “ 无类型 ” 的语言
相比较而言,C 语言提供了很多数据类型
其基本类型包括字符、具有多种长度的整型和浮点数等
另外,还有通过指针、数组、结构和联合派生的各种数据类型
由于 C 语言很适合用来编写编译器和操作系统,因此被称为 “ 系统编程语言 ”
但它同样适合于编写不同领城中的大多数程序
C 语言已经成为全球程序员的公共语言
并由此诞生了两个新的主流语言 C++ 与 Java —— 它们都建立在 C 语言的语法和基本结构的基础上
现在世界上的许多软件都是在 C 语言及其衍生的各种语言的基础上开发出来的
很多年来,C 语言的定义就是《The C Programming Language》第 1 版中的参考手册
1983 年,美国国家标准协会(ANSI)成立了一个委员会
其目标是制定一个 “ 无歧义性的且与具体机器无关的 C 语言定义 ”,而同时又要保持 C 语言原有的 “ 精神 ”
最后的结果就是 1988 年完成的 ANSI 标准,即 “ ANSI C ”
这个标准同时也被国际标准化组织(ISO)接受为国际标准,使世界各地的用户团体部受益于这一标准
这个标准是基于以前的参考手册制定的,语言本身只做了相对较少的改动
这个标准的目标之一就是确保现有的程序仍然有效,或者当程序无效时,编译器会对新的定义发出警告信息
对大部分程序员来说,最重要的变化是函数声明和函数定义的新语法
现在,函数声明中可以包含描述函数实际参数的信息
相应地,定义的语法也做了改变
这些附加的信息使编译器很容易检测到因参数不匹配而导致的错误,这个扩充对语言非常有用
新标准还对语言做了一些细微的改进
将广泛使用的结构赋值和杖举定义为语言的正式组成部分
可以进行单精度的浮点运算
明确定义了算术运算的属性,特别是无符号类型的运算
对预处理器进行了更详尽的说明
这些改进对大多数程序员的影响比较小
标准委员会考虑到 C 语言在多民族使用的情况
在语言本身以及库中都提供了对 “ 宽字符 ” 的支特
这是以中文以及其它不使用罗马字符集的语言来表示文本所需要的
该标准的第二个重要贡献是为 C 语言定义了一个函数库
它描述了诸如访问操作系统(如读写文件)、格式化输入/输出、内存分配和字符串操作等类似的很多函数
该标准还定义了一系列的标准头文件,它们为访问函数声明和数据类型声明提供了统一的方法
这就确保了使用这个函数库与宿主系统进行交互时程序之间具有兼容的行为
该函数库很大程度上与 UNIX 系统的 “ 标准 I/O 库 ” 相似
由于大多数计算机本身就直接支持 C 语言提供的数据类型和控制结构
因此只需要一个很小的运行时库就可以实现自包含程序
由于程序只能够显式地调用标准库中的函数,因此在不需要的情况下就可以避免对这些函数的调用
除了其中隐藏的一些操作系统细节外,大部分库函数可以用 C 语言编写,并可以移植
尽管 C 语言能够运行在大部分的计算机上,但它同具体的机器结构无关
只要稍加用心就可以编写出可移植的程序,即可以不加修改地运行于多种硬件上
ANSI 标准明确地提出了可移植性问题,并预设了一个常量的集合,借以描述运行程序的机器的特性
C 语言不是一种强类型的语言,但随着它的发展,其类型检查机制已经得到了加强
尽管 C 语言的最初定义不赞成在指针和整型变量之间交换值,但并没有禁止,不过现在已经不允许这种做法了
ANSI 标准要求对变量进行正确的声明和显式的强制类型转换
这在某些较完善的编译器中已经得到了实现
新的函数声明方式是另一个得到改进的地方:编译器将对大部分的数据类型错误发出警告,并且不自动执行不兼容数据类型之间的类型转换
不过,C 语言保持了其初始的设计思想,即程序员了解他们在做什么,唯一的要求是程序员要明确地表达他们的意图
C 语言不提供直接处理诸如字符串、集合、列表或数组等复合对象的操作
虽然可以将整个结构作为一个单元进行拷贝,但 C 语言没有处理整个数组或字符串的操作
除了由函数的局部变量提供的静态定义和堆栈外,C 语言没有定义任何存储器分配工具,也不提供堆和无用内存回收工具
C 语言本身没有提供输入/输出功能,没有 READ 或 WRITE 语句,也没有内置的文件访问方法
所有这些高层的机制必须由显式调用的函数提供
C 语言的大部分实现已合理地包含了这些函数的标准集合
C 语言只提供简单的单线程控制流,即测试、循环、分组和子程序,它不提供多道程序设计、并行操作、同步和协同例程
同任何其它语言一样,C 语言也有不完美的地方,某些运算符的优先级是不正确的,语法的某些部分可以进一步优化
尽管如此,对于大量的程序设计应用来说,C 语言是一种公认的非常高效的、表示能力很强的语言