汉扬编程 C语言入门 C 语言的故事:一个差点夭折的编程鼻祖

C 语言的故事:一个差点夭折的编程鼻祖

C 语言的故事:一个差点夭折的编程鼻祖

C 语言的故事:一个差点夭折的编程鼻祖

随着人工智能的爆红,全民学编程似乎已经成为一种风尚,各种Java、PHP、Ruby或Python语言的培训课程如雨后春笋般涌现。

C 语言的故事:一个差点夭折的编程鼻祖

C 语言的故事:一个差点夭折的编程鼻祖

不过,对于真正科班出身的程序员或理工科背景的人来讲,学生时代印象最深刻的编程语言应该还是非C语言莫属。

C 语言的故事:一个差点夭折的编程鼻祖

C 语言的故事:一个差点夭折的编程鼻祖

事实上,C语言影响了自20世纪80年代以来开发的几乎所有编程语言。一些语言如C++、C#和objective C语言成为了该语言的直接继承者,而其他语言也不过是采用和改编了C的语法。

我们甚至可以说,C语言几乎就是程序员之间的通用语言。

但是,C语言并不是完全凭空出现的,它的故事还要从一个“跳棋”小游戏讲起。

“能够写出完美程序的人”

二战后,战争期间延续下来的密码学和计算机技术催生出了“程序员”这一新的社会角色。

在英国,就有一位被称为“能够写出完美程序的人”——克里斯托弗·斯特雷奇(Christopher Strachey)。

斯特雷奇于1916年出生在英国的一个的名门望族,他的叔叔莱顿·斯特雷奇(Lytton Strachey)是二战期间文人团体布卢姆茨伯里派(Bloomsbury Group)的创始人之一,而他的父亲奥利弗·斯特雷奇(Oliver Strachey)则在两次世界大战期间都对盟军的密码破译活动起到了重要作用。

克里斯托弗·斯特雷奇

虎父无犬子,斯特雷奇自己最终也成为公认的编程和计算机科学专家。

在二战期间,斯特雷奇为英国一家电子公司工作,之后成为一名教师,最终落户于伦敦最负盛名的公立学校哈罗公学(Harrow)。

1951年,斯特雷奇经人介绍认识了英国国家物理实验室的迈克·伍德格(Mike Woodger),这是他第一次接触到计算机。

在用一天的时间熟悉了实验室的Pilot ACE计算机之后,他回到哈罗公学,用空闲时间钻研如何教计算机下跳棋。

第一次的努力并没有取得成果,Pilot ACE根本没有玩跳棋所需的存储容量。当时计算机的价值主要在于它们快速解方程的能力,但斯特雷奇对它们执行逻辑任务的能力更感兴趣。

那年春末,他发现了曼彻斯特大学有费兰蒂马克一型(Ferranti Mark I)计算机,而鼎鼎大名的艾伦·图灵(Alan Turing)恰好是该校计算机实验室的助理主任。

图灵曾写过程序员手册,斯特雷奇与图灵在剑桥大学时就很熟,于是向他要了一份手册。

1951年7月,斯特雷奇有机会访问曼彻斯特,并亲自与图灵讨论他的跳棋程序。图灵给他留下了深刻的建议——第一步,写一个程序,使费兰蒂马克一号能够模拟自己。

模拟器可以让程序员一步步看到计算机如何执行程序。这样的“跟踪”程序将突出程序造成瓶颈或运行效率低下的地方。在那个计算机内存和处理器周期都很昂贵的时代,这是编程的一个重要方面。

当时,斯特雷奇编写的跟踪程序有一千多条指令,它是为Ferranti Mark I编写过的最长的程序。

克里斯托弗·斯特雷奇与Ferranti Mark I计算机

很快,斯特雷奇引起了英国国家研究与发展公司总经理哈斯伯里勋爵(Lord Halsbury)的注意,他很快就聘请斯特雷奇,以推动英国大学计算机科学快速发展的实际应用。

正是在这个职位上,他发现了剑桥大学正在进行的一个项目,该项目由一个名叫大卫(David)的程序员三人组负责。

三人分别为大卫·哈特利(David Hartley)、大卫·惠勒(David Wheeler)和大卫·巴伦(David Barron),正是这三人参与了C语言的早期开发。

新语言五人组

剑桥大学的计算中心有很强的服务意识。数学实验室的第一台计算机EDSAC和EDSAC 2提供给大学其他地方的研究人员使用,他们编写的程序被打印在纸带上,然后输入机器。

在计算中心,这些纸带被夹在晾衣绳上,在工作时间内一个接一个地执行。这一排排待处理的程序被称为“作业队列”,这个术语至今仍被用来描述更复杂的组织计算任务的方法。

在EDSAC 2上线仅两年后,剑桥大学就意识到,很快就需要一台功能更强大的机器,为了实现这一目标,他们需要购买一台商用主机。剑桥大学同时考虑了IBM 7090和Ferranti Atlas,但发现都买不起。

1961年,Ferranti公司的部门经理彼得·霍尔(Peter Hall)建议他们可以与剑桥大学联合开发Atlas计算机的简化版。剑桥大学将得到这台名为“泰坦”(Titan)的原型机,而Ferranti公司则可以将新计算机推销给那些买不起Atlas系统的客户。

为了向大学的其他学生提供计算服务,这台新计算机既需要一个操作系统,也需要至少一种高级编程语言。

但当时几乎没人考虑过要扩展为EDSAC 2开发的语言。“在20世纪60年代早期,人们普遍认为,‘我们正在建造一台新的计算机,所以我们需要一种新的编程语言’。”大卫·哈特利在2017年的一次播客中回忆道。

“开发新的操作系统是必需的,”据哈特利说,但新的编程语言却不是。“我们起初只是带着玩一玩的心态开发新语言,没想到事后证明竟是一件蠢事。”

负责监督Titan项目的莫里斯·威尔克斯(Maurice Wilkes)也认为,没有必要使用新的编程语言。

Titan的主要理由是为剑桥大学的其他学生提供计算服务,为此,最好的办法是让机器尽快启动和运行,并配备用户已经熟悉的语言。

在批准开发新语言的提案之前,威尔克斯要求对现有的编程语言进行分析。

最终,在1962年6月,三人组准备了一篇论文,认为有必要开发一种新的语言。

这种新的编程语言被称为CPL(剑桥编程语言),到1963年,工作已经顺利展开。

来自伦敦大学的约翰·巴克斯顿(John Buxton)和埃里克·尼克松(Eric Nixon)加入了剑桥程序员的行列。

随着项目的发展,威尔克斯决定请本文主角斯特雷奇来监督这个项目。这群研究新语言的人会在剑桥或伦敦开会。

那时,大卫·惠勒已经转战其他项目,留下了一个五人团队:哈特利、巴伦、布克斯顿、尼克松和斯特雷奇。

哈特利很喜欢在CPL工作,“这其实是一份相当有趣的工作,”他回忆说。“我们会对一些事情进行非常激烈的讨论,最后开始互相扔纸飞机。”

这群人一开始就制定了ALGOL 60的规范,目标是写出一种“完美”的语言——一种既适用于各种用户,又美观、高效的语言。

但很快,他们就遇到了一些困难,有一个小争议是斯特雷奇反对“IF……THEN……ELSE”语句的语法。他更喜欢“OR”,但这与几乎所有其他编程语言中使用“OR”的方式相冲突。

尽管如此,他的喜好还是延续了下来,CPL参考手册在用户本以为是“ELSE”的地方加入了 “OR”。

另外,团队还投入了宝贵的时间来开发一种避免使用星号(*)来表示乘法的方法。在这里,美学上的考虑导致问题变得复杂,延迟了编程语言的实现,因为必须制定复杂的规则来区分“3a”(意思是“3*a”)和“3a”(作为变量名)。

与此同时,剑桥大学的用户对该校新的Atlas计算机缺乏可用的编程语言越来越感到沮丧。该语言的规格基本完成,但没有可用的编译器。工作组把CPL搞得非常复杂,以至于早期编写编译器的尝试导致机器代码的效率非常低。

从“B”到“C”

1965年,斯特雷奇前往麻省理工学院呆了几个月,回来后,他担任了牛津大学编程研究组的主任。与此同时,马丁·理查兹(Martin Richards)也加入了CPL项目。他开始着手开发一个可以提供给用户的有限版本的CPL——BCPL。

在麻省理工学院期间,斯特雷奇帮助马丁·理查兹安排了两年的学术休假,1966年,理查兹带着BCPL来到了马萨诸塞州,在那里,他得以继续BCPL编译器的开发工作。

BCPL是一种“自举法”(Bootstrapping)语言,因为它的编译器能够自我编译。基本上,BCPL编译器的一小块是用汇编或机器代码编写的,编译器的其余部分将用BCPL的相应子集编写。

用BCPL编写的编译器部分将被输入到用汇编代码编写的部分,由此产生的编译器程序可以用来编译任何用BCPL编写的程序。

“自举法”编译器极大地简化了将语言从一台计算机或操作系统移植到另一台计算机或操作系统的过程。只需要在编译器中写的相对较小的特有代码,就可以使编译器能够在另一台计算机上运行。

当理查兹在麻省理工学院研究BCPL编译器时,MIT正与贝尔实验室和GE公司一起参与Multics项目。为了支持这个项目,麻省理工学院和贝尔实验室建立了一个网络。

贝尔实验室

尽管两地之间的网络连接名义上是为了促进Multics的工作,但在MIT的主机上“徘徊”查看其他项目也是被接受的,肯·汤普森(Ken Thompson)就是这样找到BCPL的代码和文档的。他把它下载到贝尔实验室的一台主机上,开始使用它。

大约在汤普森进行 BCPL 实验的时候,贝尔实验室退出了Multics联盟,汤普森工作的计算机科学部门暂时没有任何类型的计算机。

最终,他们获得了一台手工制作的Digital PDP-7计算机,即使以那个时代的标准来看,也不是特别强大。尽管如此,汤普森还是在那台机器上启动并运行了第一个版本的Unix。

PDP-7 有 8,192 个“字”的内存(在这个例子中,一个字是 18 位,当时业界还没有标准化的 8 位“字节”)。Unix 占用了前 4k,留下 4k 空闲的空间来运行程序。

汤普森把他的BCPL副本进一步压缩,使它能适应PDP-7上可用的4k内存。

在这个过程中,他借用了他在加州大学伯克利分校学习时遇到的一种语言。那个语言“SMALGOL”是ALGOL 60的一个子集,旨在运行在功能较弱的计算机上。

汤普森最终在PDP-7上使用的语言是“BCPL语义与大量的SMALGOL语法的结合体”,这意味着它看起来像SMALGOL,工作起来像BCPL。

由于这种新语言只包含了BCPL中汤普森认为最有用的方面,而且可以装进相当狭窄的PDP-7中,所以他决定将“BCPL”这个名字缩短为“B”。

此前,汤普森曾用汇编器为PDP-7编写了Unix,但即使在1969年,这也不是编写操作系统的理想方式。它对PDP-7有用,因为那台计算机相当简单,而且汤普森编写操作系统主要是为了自娱自乐。

任何一个操作系统,如果要由多个程序员维护和更新,并能在当时比较复杂的硬件上运行,就需要用高级编程语言来编写。

因此,当贝尔实验室在1971年为该部门购买了一台PDP-11时,汤普森决定用高级编程语言重写Unix。

与此同时,丹尼斯·里奇(Dennis Ritchie)已经采用了B语言,并将其改编为在更强大的计算机上运行。

他首先在B语言中添加的第一个东西是“输入”变量的能力。因为PDP-7的内存是由18位字组成的,所以B语言可以通过将每个变量看作是一个单一的内存字,或者是一个连续的字,通过它们在系统内存中的位置进行引用来简化。

这样的方法在内存很小、用户基数很小的简单机器上是有效的,但在更复杂的系统上,程序更复杂,用户更多,这可能导致确定一个变量是字符串还是数字需要特殊手段,同时造成内存使用效率低下。

里奇将这种修改后的语言命名为“New B”,缩写为NB(呃,误打误撞的谐音梗!)。它被安装在Murray Hill计算中心的主机上,这使得整个贝尔实验室的用户都可以使用它。

自然,当汤普森决定用高级语言重写Unix时,他从NB开始,可惜他的前三次尝试都以失败告终。

每次出现故障,里奇都会以一种对他和汤普森来说有意义的方式为 NB 添加功能,而且一旦他添加了结构,汤普森就能够用这种新语言编写 Unix。

于是,里奇和汤普森认为结构体的加入是一个重大的变化,有足够的理由为编程语言重新命名,于是B语言变成了C语言。

走向世界

随着商业化条件的成熟,C语言和Unix开始走出贝尔实验室。

在这过程中,PDP-11迅速成为市场上最成功的微型计算机之一对C语言和Unix的推广功不可没。

任何拥有PDP-11的计算中心都可以在上面安装Unix,而Unix的低成本使它对大学特别有吸引力。于是,C与Unix一起出现在大学生面前。

1978年,里奇和布莱恩·柯林汉(Brian Kernighan)出版的《C编程语言》进一步推动了C语言的成功。即使在当时,这本228页的薄书也是一本非常简单易懂的著作。

C语言语法的广泛传播影响了许多后续语言的发展。不过,汤普森从都不相信C语言会像现在这样普及,“我的美学意识告诉我,一种语言不可能覆盖整个宇宙。”汤普森说。

和Unix一样,C语言也是在失败中诞生的成功产物。Multics 催生了 Unix,在其鼎盛时期,全球只在约80台计算机使用。而最终产生了C语言的CPL在1967年还没完成就被剑桥大学的研究人员放弃了。

当斯特雷奇在牛津大学成立程序设计研究小组时,他说:“把实际工作和理论工作分开是人为的,是有害的。”而CPL的本意是将实践和理论的关注点结合起来。

正如汤普森回忆道,“C语言是为了Unix而写的,而Unix是为了让我们所有人都能写程序而写的。”

参考资料:://arstechnica.com/features/2020/12/a-damn-stupid-thing-to-do-the-origins-of-c/

本文来自网络,不代表汉扬编程立场,转载请注明出处:http://www.hyzlch.com/cjia/6694.html

预算有限想买豪车?2021款奔驰C级,不妨了解一下

C语言的for循环,到底有多深?代码路滑,小心点

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部