C语言发展史:腾讯 IEG 运营开发工程师万字奉献

C语言语言发展史

任何一种新事物的出现都不是来自于偶然,而是时代所驱使的必然结果。

1.1 C语言有多伟大

如果你问我:C语言有多伟大。那么,我可能会想一下,说:多伟大我不知道,但是我知道很伟大。

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

这里,我想说一句可能有点片面的话,就是:如今这世界上,凡是带电的地方,可能都会有她(C语言)或者她的子孙的影子。

任何比C语言更低级的语言,都不足以完整地抽象一个计算机系统;任何比C高级的语言,都可以用C来实现。

丹尼斯·麦卡利斯泰尔·里奇(英语:Dennis MacAlistair Ritchie,1941年9月9日-2011年10月12日),美国计算机科学家。黑客圈子通常称他为“dmr”。他是C语言的创造者、Unix操作系统的关键开发者,对计算机领域产生了深远影响,并与肯·汤普逊同为1983年图灵奖得主。

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

丹尼斯.里奇 生平时间线

麻省理工大学计算机系的马丁教授评价说:"如果说,乔布斯是可视化产品中的国王,那么里奇就是不可见王国中的君主。乔布斯的贡献在于,他如此了解用户的需求和渴求,以至于创造出了让当代人乐不思蜀的科技产品。然而,却是里奇先生为这些产品提供了最核心的部件,人们看不到这些部件,却每天都在使用着。"

克尼汉评价道:牛顿说他是站在巨人的肩膀上,如今,我们都站在里奇的肩膀上。

这段文字出自C语言之父丹尼斯.M.里奇所写的一篇关于《C语言发展史》的文章,文中明确指出C语言源自于B、BCPL两种语言。可以把C语言看做是站在巨人的肩上,顺应时代潮流的后浪。

Martin Richards's BCPL Reference Manual, 1967 https://web.archive.org/web/20080622171914/http://cm.bell-labs.com/cm/cs/who/dmr/bcpl.html

马丁·理查德(英语:Martin Richards,1940年7月21日-),生于英国,计算机科学家,为BCPL编程语言的发明者,发展了TRIPOS操作系统。

1966年,马丁·理查德在剑桥大学,以CPL编程语言为基础,发明了BCPL编程语言。

肯尼斯·兰·汤普逊(英语:Kenneth Lane Thompson,1943年2月4日-)小名肯·汤普逊(英语:Ken Thompson),美国计算机科学学者和工程师。黑客文化圈子通常称他为“ken”。在贝尔实验室工作期间,汤普逊设计和实现了Unix操作系统。他创造了B语言(基于BCPL) — C语言的前身,而且他是Plan 9操作系统的创造者和开发者之一。与丹尼斯·里奇同为1983年图灵奖得主。

2006年,汤普逊进入Google公司工作,与他人共同设计了Go语言。

站在巨人的肩上

与优秀之人为伍

不畏得失,做有趣的事

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

左Ken 右Dennis | 右上角:Unix标识牌

言传身教

感谢丹尼斯.里奇留给了这世界一本“C语言圣经”

可惜的是,当年笔者大学学的是谭浩强谭老师的C语言

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

Dennis与《The C Programming Language》

互相成就

终成正果

你做了什么,最终会被世人看到

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

1999年获得美国国家技术奖 [左一:Ken | 左二:Dennis | 右一:克林顿]

从这些老照片中,我隐隐约约看到了几行小字,写着:

1.与优秀之人为伍

2.互相成就

试想,有多么重要?

上图时间线只显示前几个与C语言在相同时间段内诞生的Unix版本(当然,感兴趣的话,可以查询Unix相关发展史,绝对会让你大吃一惊。其中最著名的几个分支:BSD、minix、Linux...)。

下面,通过在网上找得到的部分Unix内核源码,来追溯一下C语言出现的时机。

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

PDP-7 Unix https://minnie.tuhs.org/cgi-bin/utree.pl?file=PDP7-Unix

可以看到基本都是用汇编写的(文件名后缀.s)。为什么用基本这个词呢?因为,在系统里面有一部分命令是用B语言写的。

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V1

可以看到,还是用汇编写的(文件名后缀.s)。

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

Second Edition Unix The second edition of Unix was developed for the PDP-11 at Bell Labs by Ken Thompson, Dennis Ritchie and others. It extended the First Edition with more system calls and more commands. This edition also saw the beginning of the C language, which was used to write some of the commands.

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2

https://zhuanlan.zhihu.com/p/136102461

此处的代码仅是某些命令,某些库函数和C编译器的源代码。c /中的文件来自 last1120c.tar.gz 磁带,并构成了第二版Unix的有效C编译器。

下载地址:http://minnie.tuhs.org/Archive/Applications/Early_C_Compilers/last1120c.tar.gz

The second edition of Unix was developed for the PDP-11 at Bell Labs by Ken Thompson, Dennis Ritchie and others. It extended the First Edition with more system calls and more commands. This edition also saw the beginning of the C language, which was used to write some of the commands.

The code here is only the source to some of the commands, some of the library functions, and the C compiler. The files in c/ come from the last1120c.tar.gz tape, and form a working C compiler for Second Edition Unix.

https://minnie.tuhs.org/cgi-bin/utree.pl?file=V2

下载源码解压缩之后,目录结构如下:

C语言发展史:腾讯 IEG 运营开发工程师万字奉献

感兴趣的小伙伴可以下载下来研究一下。

2. BCPL、B、C语言比较

如果想要找到一种好的方式,来进行编程语言之间比较的话,那么非代码莫属。

2.1 3种语言代码示例

下面分别使用BCPL、B、C三种语言实现一个简单的程序:程序将三个数字a、b、c相加,并将结果赋值给sum,最后打印总和。

2.1.1 BCPL语言示例

BCPL https://zh.wikipedia.org/wiki/BCPL

GET "libhdr"

LET start() = VALOF
{ LET a, b, c = 1, 2, ,3

    sum := a + b + c
    writen(sum)
}
  • LET 声明变量
  • := 符号为赋值符号 Go中也有该符号,表示函数内部局部变量。这里感觉很有意思的一点是:最初B语言之父肯.汤普逊把:=符号改成了=符号。现在,也作为Go语言之父之一,又把:=符号请回来了(冥冥之中的命运~)。

从BCPL到B的过渡中,决定使用单个字符 = 代替赋值 :=

Other fiddles in the transition from BCPL to B were introduced as a matter of taste, and some remain controversial, for example the decision to use the single character = for assignment instead of :=. Similarly, B uses /**/ to enclose comments, where BCPL uses //, to ignore text up to the end of the line. The legacy of PL/I is evident here. (C++ has resurrected the BCPL comment convention.) Fortran influenced the syntax of declarations: B declarations begin with a specifier like auto or static, followed by a list of names, and C not only followed this style but ornamented it by placing its type keywords at the start of declarations.

https://www.bell-labs.com/usr/dmr/www/chist.html

B语言的语言结构

main() {
    -- statements --
}

newfunc(arg1, arg2) {
    -- statements --
}

fun3(arg) {
    -- more statements --
}

B语言代码示例

main() {
  auto a, b, c, sum;

  a = 1; b = 2; c = 3;
  sum = a+b+c;
  putnumb(sum);
}
  • 语句auto ...是一个声明。即,它定义了要在函数内使用的局部变量
  • putnumb 是一个带参数的库函数,它将在终端上打印一个数字