精华内容
下载资源
问答
  • C语言的发展史

    2016-12-02 22:55:11
    C语言的发展史 C语言是一门通用的,模块化,程序化的编程语言,被广泛应用于操作系统和应用软件的开发。由于其高效和可移植性,适应于不同硬件和软件平台,深受开发员的青睐。 C语言早期发展 1969-1973年在...

    C语言的发展史

    C语言是一门通用的,模块化,程序化的编程语言,被广泛应用于操作系统和应用软件的开发。由于其高效和可移植性,适应于不同硬件和软件平台,深受开发员的青睐。

    C语言早期发展


    1969-1973年在美国电话电报公司(AT&T)贝尔实验室开始了C语言的最初研发。根据C语言的发明者丹尼斯·里奇 (Dennis Ritchie) 说,C 语言最重要的研发时期是在1972年。


    说明:丹尼斯·里奇(Dennis Ritchie),C语言之父,UNIX之父。1978年与布莱恩·科尔尼干(Brian Kernighan)一起出版了名著《C程序设计语言(The C Programming Language)》,现在此书已翻译成多种语言,成为C语言方面最权威的教材之一。2011年10月12日(北京时间为10月13日),丹尼斯·里奇去世,享年70岁。


    C语言之所以命名为C,是因为C语言源自Ken Thompson发明的 B语言,而B语言则源自BCPL语言。


    C语言的诞生是和UNIX操作系统的开发密不可分的,原先的UNIX操作系统都是用汇编语言写的,1973年UNIX操作系统的核心用C语言改写,从此以后,C语言成为编写操作系统的主要语言。
    K&R C


    1978年,丹尼斯·里奇(Dennis Ritchie)和布莱恩·科尔尼干(Brian Kernighan)出版了一本书,名叫《The C Programming Language》(中文译名为《C程序设计语言》)。这本书被C语言开发者们称为“K&R”,很多年来被当作C语言的非正式的标准说明。人们称这个版本的C语言为“K&R C”。


    1988年丹尼斯·里奇(Dennis Ritchie)和布莱恩·科尔尼干(Brian Kernighan)修改此书,出版了《The C Programming Language》第二版,第二版涵盖了ANSI C语言标准。第二版从此成为大学计算机教育有关C语言的经典教材,多年后也没再出现过更好的版本。
    ANSI C 和 ISO C


    1970到80年代,C语言被广泛应用,从大型主机到小型微机,也衍生了C语言的很多不同版本。


    为统一C语言版本,1983年美国国家标准局(American National Standards Institute,简称ANSI)成立了一个委员会,来制定C语言标准。1989年C语言标准被批准,被称为ANSI X3.159-1989 "Programming Language C"。这个版本的C语言标准通常被称为ANSI C。又由于这个版本是 89 年完成制定的,因此也被称为 C89。


    后来 ANSI 把这个标准提交到 ISO(国际化标准组织),1990年被 ISO 采纳为国际标准,称为 ISO C。又因为这个版本是1990年发布的,因此也被称为C90。


    ANSI C(C89) 与 ISO C(C90)内容基本相同,主要是格式组织不一样。


    因为 ANSI 与 ISO 的C标准内容基本相同,所以对于C标准,可以称为ANSI C,也可以说是ISO C,或者 ANSI / ISO C。


    注意:以后大家看到 ANSI C、ISO C、C89、C90,要知道这些标准的内容都是一样的。


    C语言对其它语言的影响


    很多编程语言都深受C语言的影响,比如C++(原先是C语言的一个扩展)、C#、Java、PHP、Javascript、Perl、LPC和UNIX的C Shell等。


    也正因为C语言的影响力,掌握C语言的人,再学其它编程语言,大多能很快上手,触类旁通,很多大学将C语言作为计算机教学的入门语言。


    目前,几乎所有的开发工具都支持 ANSI / ISO C 标准。是C语言用得最广泛的一个标准版本。
    C99


    在ANSI C标准确立之后,C语言的规范在很长一段时间内都没有大的变动。1995年C程序设计语言工作组对 C语言进行了一些修改,成为后来的1999年发布的 ISO/IEC 9899:1999标准,通常被成为C99。


    但是各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的時候,微软和Borland却似乎对此不感兴趣。


    说明:GCC(GNU Compiler Collection,GNU编译器集合)是一套由GNU工程开发的支持多种编程语言的编译器。


    综上所述,目前广泛使用的C语言版本是 ANSI / ISO C,最经典的C语言教材是《C程序设计语言(The C Programming Language) 第二版》。

    展开全文
  • C语言的发展史 最初的C语言只是为编写UNIX操作系统提供的一种工作语言,1973年,Ken Thompson 和D.M.Ritchie合作把UNIX的90%以上用C语言改写(原来的UNIX操作系统是用汇编语言编写的) 后来主要用在贝尔实验室...
      1. C语言的发展史        最初的C语言只是为编写UNIX操作系统提供的一种工作语言,1973年,Ken Thompson 和D.M.Ritchie合作把UNIX的90%以上用C语言改写(原来的UNIX操作系统是用汇编语言编写的)
        1. 后来主要用在贝尔实验室内部使用(先后移植在大、中、小、微型计算机)
        2. 以1978年发布的UNIX第7版中的C语言编译程序为基础,Brian.W.Kernighan和Dennis M.Ritchie(合称K&R)合著了影响深远的名著 The C Programming Language,后来被称为标准的C
        3. 1983年,美国国家标准化协会(ANSI)根据C语言问世以来的各种版本对C语言的发展和扩充,制定了新的标准草案,即83 ANSI C
        4. 1989年,ANSI又公布了一个新的C语言标准-ANSI X3.159-1989(简称C89)
        5. 1990年,国际标准化组织ISO接受C89,作为国际标准ISO/IEC 9899:1990,通常简称C90(注意:ISO的C90和ANSI的C89基本上一致。
        6. 1995年,ISO对C90作了一些修改,称为C95.
        7. 1999年,ISO又对C语言标准进行了修订,在基本保持原来的C语言的基础上,又增加了一些面向对象的特征,命名为ISO/IEC 9899:1999,简称C99

    C语言在计算机科学与技术专业学习中地位

      1. C语言功能强大,使用灵活,既可以用于编写应用软件,又用于编写系统软件。
      2. 熟练掌握C语言是在计算机科学与技术专业学习中计算机开发人员的一项基本功。

    转载于:https://www.cnblogs.com/KLDYG1/p/9318770.html

    展开全文
  • C语言的发展史-2

    千次阅读 2013-06-03 00:13:32
    C语言的发展史1 原文 The Development of the C Language yqj2065自己翻译一下。备用。

    C语言的发展史1   原文 The Development of the C Language

    不满足网上的译文,yqj2065自己翻译一下。备用。【】是译注、补充。


    更多的历史

        在TMG版本的B工作之后,Thompson利用B重写了B(的编译器)(一个自举步骤)。在开发途中,他不断地与内存限制作斗争:每一个语言[特性]的添加都会使编译器膨胀从而令内存几乎不够用,但每次利用该特性的优点的重写又减少了编译器的大小。例如,B引入复合(广义)赋值运算符,x=+y用于将y加到x。这一标记通过McIlroy——他将它合并到他实现的一个TMG版本中——从Algol 68[Wijngaarden 75]中获得。(在B和早期C中,该运算符被拼作=+而非+=;这个错误——在1976年被修复——是因为第一种形式在B的词法分析中更为简单)。

        Thompson通过发明自增++和自减--运算符,又向前走了一步。它们的前缀或后缀位置决定了变化是发生在计算操作数的值之前或之后。它们并没有出现在B的最早版本中,而是在发展途中出现的。人们经常猜测,它们之所以出现,是因为C和Unix刚开始流行于DEC PDP-11时机器提供的自增和自减地址模式【如同很多人把垃圾回收看成是Java的贡献】。从时间上看,这是不可能的,因为B被发明的时候还没有PDP-11。当然,PDP-7的确有少量“自增”内存单元,具有通过它们一个间接内存引用能够自增该单元的特性。该特征或许暗示了Thompson创造那些运算符;但能够前缀和后缀则完全是他个人的创造。实际上,自增单元并没有直接用于该操作符的实现,这种创新的一个更强烈的动机可能是他发现,翻译++x比x=x+1尺寸上小。

        PDP-7上的B编译器并不产生机器指令而是“线索码”(threaded code)[Bell 72]【yqj2065不知道有没有好的术语翻译,参考http://en.wikipedia.org/wiki/Threaded_code】,这是一种解释器方案,编译器的输出由一系列执行基本操作的代码片段的地址构成。这些操作通常运行于一个简单堆栈上,特别对B而言。

        PDP-7的Unix系统上,除了B本身外,只有很少的东西是B编写的,因为这个机器除了试验外,做什么都显得太小和太慢;用B完整地重写操作系统和库,从可行性上看代价太高昂;在某种程度上,Thompson通过所提供的“virtual B”编译器解决地址空间拥挤问题、通过对解释器中的代码和数据分页,使得被解释(执行)的程序拥有超过8K字节(的空间),但是对于通用库的实用而言,这样太慢了。尽管如此,还是出现一些用B写的工具,包括Unix用户熟悉的可变精度计算器dc的一个早期版本[McIlroy 79]。【看来,Ritchie很自觉地当Thompson一个小弟】我所承担的最有意义的工作是一个真正的编译器,将B程序翻译为GE-635机器指令而非线索码。它是一个小杰作:一个用本身语言写的完全的B编译器,它为36位大型机生成代码,运行于有4k字长的用户地址空间的18位机器上。这个项目之所以可能,完全是因为B的简单性和它的运行时系统。

        尽管我们时而意淫一下去实现一个如同当时的Fortran, PL/I或Algol 68那样的主流语言,相对于我们的资源——可用的是如此简单和小的工具,这样的项目是令人绝望地庞大。所有这些语言都影响了我们的工作,但是用我们自己(的语言)做事情则更有趣。

       到了1970年,Unix项目显得很有(成功的)希望,我们才能够申请新的DEC PDP-11。该处理器是DEC生产线的第一批产品,而且过了三个月磁盘才到。使用线索码技术为它编写B程序,仅需要为运算符编写代码段和一个简单的汇编器——我用B编写的。不久,在(拥有)操作系统之前,dc成为我们的PDP-11上被测试的第一个有趣的程序。几乎是最快的(速度),还在等待磁盘时,Thompson用PDP-11的汇编语言重写了Unix内核和一些基本命令。从该机器的24KB内存中,最早的PDP-11 Unix系统给了操作系统12KB,一个很小的空间分给用户程序,剩下的作为RAM磁盘。这个版本仅用于测试而非实际工作;the machine marked time by enumerating closed knight's tours on chess boards of various sizes.磁盘到达后,我们把汇编语言转换为PDP-11上的方言后,很快移植到它上面,也移植了那些已经用B编写的程序。
        到1971年时,我们这个小小的计算机中心开始有了用户。我们都希望更容易地编写有趣的软件。使用汇编太让人郁闷了,因而即使B有性能问题,B已经有了一个包含有用服务例程的小例程库,并被越来越多的新程序使用。这段时期的最著名的成果之一,是Steve Johnson编写的yacc解析-生成器的第一个版本[Johnson 79a]。

    B的问题

        最开始,我们在按字编址的机器上使用BCPL和B语言,这些语言的单一数据类型——“单元”,轻松地等价硬件的机器字。PDP-11的到来暴露了B的语义模型的一些不足。首先,它继承于BCPL的、仅作出少量改变的字符处理机制是笨拙的:在一个面向字节的机器上,使用库例程把打包的字符串展开到一些独立的单元然后再次包装,或者访问或替换单个字符,开始变得讨嫌甚至无聊。
        其次,尽管最初的PDP-11没有提供浮点算术运算,但制造商承诺将很快提供。在我们的Multics项目和GCOS编译器中,通过定义特别的运算符,浮点运算已经被添加到BCPL,但是该机制仅在适当的机器上可行——单个字长足够包含一个浮点数;这在16位的PDP-11上是不成立的。
        最后,B和BCPL模型在处理指针时隐含着系统开销:该语言的规则——将一个指针定义为字长数组的索引,强迫这些指针被表示为字索引。每个指针引用会导致一个运行时尺度转换,从指针变为硬件希望的字节地址。
       因为上述因素,一个类型模式看来很有必要,以便为处理字符和字节编址,以及为即将到来的浮点硬件作好准备。其他议题,特别是类型安全性和接口检查,当时并不显得如同后来那样的重要。【也是摸着石头过河啊】
       抛开语言本身的这些问题,B编译器的线索码技术使得程序比它们对应的汇编语言版本慢得太多,使得我们看不到将操作系统或它的核心库用B来重写的可能性。
    在1971年,通过添加一个字符类型和重写它的编译器以生成PDP-11机器指令而非线索码,我开始扩展B语言。因此,从B到C的过渡是与一个编译器的创作同时进行的,该编译器要能够产生足够快和小的程序以抗争汇编语言。我称这个轻微扩展的语言为NB,表示“牛逼大笑”(new B)。

    C的萌芽

    NB存在的时间太短以致于没有编写它的完整描述。它提供了int和char类型、它们的数组和指向它们的指针,声明的典型风格如下:
        int i, j;
        char c, d;
        int iarray[10];
        int ipoint[];
        char carray[10];
        char cpoint[];
    数组的语义与B和BCPL的完全一样:声明iarray和carray将分配单元,分别被所指向的十个整数或字符序列中的第一个的(地址)值所动态初始化。对ipointer和cpointer的声明省略了尺寸,以表明没有存储(空间)被自动分配。在处理时,语言的解释对指针和数组变量是同样的:一个指针声明所产生的一个单元与数组声明所产生的单元,区别仅在于(前者)由程序员给它赋值其所指,而不是让编译器分配空间和初始化该单元。
        与数组和指针名字绑定的单元所存储的值,是对应存储区的机器地址,按字节度量。因而,通过指针的间接引用,不导致将指针从字长伸缩为字节的运行时开销。另一方面,数组下标和指针算术的机器代码,现在依赖于数组或指针的类型:计算iarray[i]或ipointer+i表示移动加数i乘以被指向对象尺寸。
    这些语义意味着从B转换较容易,而我花了几个月测试它们。当我尝试扩展类型标识,特别是添加结构体(记录)类型时,麻烦比较明显了。结构体似乎应该直观地映射到机器的内存,但是,当结构体包含一个数组时,没有一个好位置存储包含数组基地址的指针,也没有便捷的方式将它初始化。例如,早期unix系统的目录条目,在C可以被描述为
        struct {
            int  inumber;
            char name[14];
        };
    我希望,结构体不仅表示抽象对象,也要描述那些可以从目录读到的比特的集合。编译器能把语义所要求的name的指针藏在哪里呢?即使结构体被更抽象地看待而且指针的空间也能以某种方式隐藏,我又该如何处理分配一个复杂对象时初始化那些指针的技术问题呢?某人或许定义的结构体包含数组而该数组却包含结构体,直到任意的深度。
    该解决方案成为无类型BCPL到类型化C进化链上的一个重要飞跃。取消在内存中该指针的存在,而是当数组名出现在表达式中时才生成指针。这个规则——延续到如今的C,含义是当数组类型出现在表达式中时,数组类型的值被转换成指向组成数组的对象中的第一个对象的指针
    尽管在这些语言的语义上根本不同,这个发明使得已有的B代码能继续工作。较少的、给数组名赋新值以调整其原点——在B和BCPL中是可能的,在C中无意义——的程序能够很容易地修改。更重要的是,新语言使用了对数组语义的一种一致和可行(或许不常见)的解释,因而打开了通往更复杂类型结构的大门。

    将C与其前辈极其明显地区别开来的第二个创新,是其较完整的类型结构,尤其是(表现)声明语句的语法(格式)的表达式。NB提供基本的类型int和char,和它们的数组,指向它们的指针,但没有更进一步的组合。更一般地:给定任意类型的一个对象,应该能够描述将若干个(对象)聚集为一个数组、从一个函数求出或指向它的指针之类的新对象。对于这种复合类型的每一个对象,已经有一种涉及低层对象的途径:索引数组,调用函数,指针上使用间接操作符。类比推理导致了声明语法,名字镜像表达式语法中名字经常出现。因此,
        int i, *pi, **ppi;
    声明一个整数(integer),一个指向整数的指针(pointer to an integer),一个指向整数的指针的指针(a pointer to a pointer to an integer)。这些声明语法反应了一种现象即当用于一个表达式时i,*pi和**pi都产生于一个int类型。类似地,
        int f(), *f(), (*f)();
    声明一个返回整型值的函数(function),返回整型指针的函数,一个指向函数的指针而返回函数的返回值为int;
        int *api[10], (*pai)[10];
    声明一个整型指针数组(an array of pointers to integers),一个指向整型数组的指针(a pointer to an array of integers)。在所有这些情况中,一个变量的声明类似于它在表达式中的用法,其类型是置于声明语句开头的那个。
    C语言采用的类型组合模式归功于Algol 68,尽管它或许没有以Algol信徒认可的形式出现。我从Algol吸取的主要概念,是一个基于原子类型(包括结构)的类型结构,组合成数组,指针(引用),和函数(过程)。Algol 68关于union(共用体)和造型(cast/类型转换)概念的影响,也在后来表现出来。
       创造了类型系统、相关的语法和新语言的编译器之后,我认为它该有个新名字;NB看起来不够独特。我决定延用单字母风格并为之取名为C,这也引发了一个问题:这个名字表示的是字母表顺序还是BCPL中的字母顺序呢?【D语言按照的是字母表顺序,而有人认为C的下一个语言应该是P】

    续...


    展开全文
  • C语言的发展史-3

    千次阅读 2013-06-06 14:24:36
    C语言的发展史C语言的发展史-2 原文 The Development of the C Language 不满足网上的译文,yqj2065自己翻译一下。备用。【】是译注、补充。 C初生 在本语言取名后,快速地变更不停,例如&&和||操作符的引入...

    C语言的发展史1   

    C语言的发展史-2

    原文 The Development of the C Language

    不满足网上的译文,yqj2065自己翻译一下。备用。【】是译注、补充。


    C初生

        在本语言取名后,快速地变更不停,例如&&和||操作符的引入。在BCPL和B中,表达式求值依赖于上下文:在if和其它条件语句中比较一个表达式的值与零,这些语言对与(&)和或(|)运算符给与了特别的解释。在普通上下文中,它们按位运算,而在这个B语句中
        if (e1 & e2) ...
    编译器必须对e1求值而且如果值为非零值,对e2求值,而且如果它也非零,则执行依赖if的语句。对于e1和e2内部的&和|操作符要求递归地计算。在这种true-值环境中的布尔运算符的短路(short-circuit)语义似乎令人满意,但是运算符的重载难以解释和运用。在Alan Snyder的建议下,我引入了&&和||运算符,使这种机制更明了。
    它们迟到地引入解释了C优先级规则上的一个不幸。B中某人编写
        if (a==b & c) ...
    来检测a和b是否相等并且c是否非零;在这样的条件表达式中,&比==的优先级低比较好。在从B转变为C时,某人希望在这种表达式中用&&代替&;为了使这种转换不那么痛苦,我们决定保持运算符&与==有相等的优先级,而仅仅把&&的优先级与&的做了细微区分。今天看来,变动&和==的相对优先级会更好,这样就能简化一个C通用的惯用法:为了测试一个掩码值和另一个值,人们必须这样写
        if ((a&mask) == b) ...
    那个内层的圆括弧是需要的,但容易被忘记。
        许多其它改变发生在1972-73年,但最重要的是引入了预处理器,部分原因是Alan Snyder[Snyder 74]的建议,也(因为)沿用在BCPL和PL/I中已存在的文件包含机制。它的原始版本极之简单,仅提供文件包含和简单字符串替换:#include和参数化宏#define。之后很快对它进行了扩展,合并了宏与参数还有条件编译。之后不久,它被扩展为带参数宏和条件编译,主要是Mike Lesk的工作,后来是John Reiser。预处理原本是作为语言本身的一个可选附件。许多年来,除了源代码在开始处包含一些特别符号外,它们不被使用。这种看法持续至今,也解释了在早期参考手册中,预处理语法与语言其它部分描述不完整,和对它的不精确描述。

    可移植性

    到1973年早期,现代C的基础部分已经完成。在那年夏天,该语言和编译器已足够强大,以允许我们用C为PDP-11重写Unix内核。(在1972年,Thompson已经简短尝试用C的早期版本——结构体之前,生成系统代码,但放弃了那次努力)也是在这段时期,编译器被转向了其它附近的机器,特别是Honeywell 635和IBM 360/370;因为语言不能独自存在,现代库的原型被开发。特别是Lesk写了一个“可移植I/O包”[Lesk 72],后来被修改成为C的“标准I/O”例程。在1978年,Brian Kernighan和我出版了The C Programming Language(C程序设计语言)[Kernighan 78]。尽管这本书没有描述一些后来变成通用的附属项,该书充当语言标准达十多年,直到一个正式的标准被采纳。尽管我们在本书上密切共事,但是分工明确:Kernighan编写了几乎所有的说明内容,而我负责包含参考内容的附录,和Unix系统的接口的那一章。

    在1973-1980年间,语言又有了一些发展:类型结构增加了unsigned, long, union和枚举类型,并且结构体几乎成为第一类对象(仅缺少一个字面值符号)。同样重要的发展出现在它的环境和其它伴随技术上。用C编写Unix内核使我们对该语言的有用性、效率有足够的信心,去重写系统的库和工具,并且随后把其中最有趣的东西移到其它平台。像在[Johnson 78a]中描述的那样,我们发现传播Unix工具的最困难的问题,并不是C语言和新硬件的接口,而在于适应其它操作系统上的现有软件。因此Steve Johnson开始了pcc——一个C编译器的工作,目的是容易移植到新机器上[Johnson 78b],在他,Thompson和我开始把Unix系统移到Interdata 8/32计算机的时候。

    在这时期,语言的变化——特别是1977年左右,主要集中在可移植性和类型安全的考虑上,努力处理在移植大量的代码到新的Interdate平台时我们预见和观察到的问题。那时的C依旧强烈地呈现出无类型根源的特征。例如在早期语言手册或存在的代码中,指针与整型内存索引几乎没有区别;字符指针和无符号整数的算术特性的相似性,使得很难抵御将它们看成同一个东西的诱惑。添加unsigned类型使得无符号算术能够不混淆于指针运算。类似地,早期语言容忍整数与指针间的赋值,但这种作法开始变得不受鼓励;一个类型转换符号(在Algol 68的例子中被称作“casts”)被发明,以更明显指示类型转换。受PL/I例子的诱惑,早期C没有将结构体指针强烈绑定到它们所指向的结构体,而是允许程序员用pointer->member但几乎不用考虑指针的类型;这样的表达式不经大脑地用作被指针指派的内存区域的引用,而成员名字仅表示一个偏移量和类型。

    尽管K&R第一版描述了把C的类型结构用于其呈现形式的大部分规则,许多程序的编写(使用了)遗留的旧式、更松散风格,而且编译器还得容忍它们。为了鼓励人们更加关注于正式的语言规则、检测合法但可疑的写法、并帮助发现分离编译中简单机制难以检测的接口的错误匹配,Steve Johnson修改其pcc而产生了lint[Johnson 79b],用于扫描一系列文件并标记可疑的写法。

    在使用中成长

    我们在Interdata 8/32的可移植性试验的成功,很快导致了Tom London和John Reiser在DEC VAX 11/780上的另一次成功。这种机器比Interdata变得更流行,并且Unix和C语言开始在AT&T公司内部和外面快速传播。尽管到1970年代中期,Unix已经被用于各种项目,包括贝尔系统的,以及我们公司外的一小群以研究为目的的机构、学院和政府机构,它的真正成长开始于达到可移植性之后。值得特别记住的是刚出现的、基于公司开发和研究团队的AT&T的计算机系统部门(推出的)System III和System V版本系统,和加州大学伯克利分校继承自Bell实验室研究组的BSD系列。
    在1980年代,C语言的使用广泛传播,并且几乎每一种机器体系结构和操作系统都有编译器;特别是它变成一种个人计算机上流行的编程工具,包括对这些机器的商业软件制造商和对编程有兴趣的终端用户。在那十年开始时,几乎每一种编译器都是基于Johnson的pcc;直到1985年,才有了许多独立开发的编译器产品。

    标准化

    到1982年,很明显,C需要正式的标准化。最近似于标准的K&R第一版,不再反应实际使用中的语言;尤其是它没有提及void和enum类型。虽然它预见了(构成)结构体的新方式,只是该书发表后语言才支持对其赋值、将其传递给函数和从函数返回它、以及将成员名字与包含它们的结构体或union严格关联。尽管AT&T发布的编译器包含了这些变化,尽管非基于pcc的编译器的大多数供应商很快添加了它们,但仍没有一个完整、权威的语言描述。

    K&R第一版在很多语言细节上也不够精确,而且对于pcc这个“参照编译器”来说,K&R日益显得不切实际;pcc甚至也没有忠实的体现被K&R描述的语言,更别说后续的扩展。最后,开始将C用于商业和政府合同项目意味着批准一个正式标准很重要。因此(在M. D. McIlroy的催促下),在1983年夏天,ANSI建立了接受CBEMA的指导的X3J11委员会,目标是制订一个C标准。X3J11在1989年末提出了一个他们的报告[ANSI 89],后来这个标准被ISO接受为ISO/IEC 9899-1990。

    从最开始,X3J11委员会在语言扩展上采取了谨慎、保守的态度。我极其满意,他们严肃地对待他们的目标:“为C程序设计语言制订一个清晰、一致和无二义性的标准,规范C的通用、现行的定义,促进不同C语言环境下的用户程序的可移植性。”[ANSI 89] 委员会意识到,仅仅靠发布一个标准并不会改变这个世界。

    X3J11仅给语言本身引入了一个但真正重要的改变:它使用从C++[Stroustrup 86]借鉴的语法,把形式参数的类型添加到函数的类型签名中。用以前的风格,外部函数是这样声明的:
        double sin();
    仅说明sin是一个函数,返回一个double(即双精度的浮点数)值。在新的风格中,这个更好的声明
        double sin(double);
    使参数类型明显因而鼓励更好的类型检查和适当的转换。即使这个添加,尽管它产生了明显更好的语言,也引起了困难。委员会有理由认为,虽然新风格更好,简单地取缔旧式风格的函数定义和声明不合适。这种必然的妥协自然产生了,尽管允许两种形式使语言复杂化,并且可移植软件的作者必须应付不符合标准的编译器。

    X3J11也引入了一大堆较小的附加和修改,例如,类型限定词const和volatile,和稍有不同的类型提升规则。尽管如此,标准化过程没有改变语言的特征。特别是,该C标准没有试图正规化定义语言语义,因而在一些小细节上还可能存在争议;然而,它很好地说明了自最初描述以来(该语言)在使用中的改变,并且对于基于它的实现而言是足够精确的。

    因此,C语言核心在标准化过程中几乎毫发无伤,并且该标准更多地表现为一个更好的、周到的法典而非一次新发明。许多重要的改变发生在语言的环境中:预处理器和库。预处理器处理宏替换,使用一些约定以区别于语言的其余部分,它与编译器的交互从未被很好描述,X3J11企图纠正这种情形。其结果明显好于K&R第一版中的解释;除了更全面,它提供了一些操作,如标记的串接,以前只能够在少数实现中可用。

    X3J11非常正确地认识到一个完整和仔细的标准C库(standard C library)的描述与它所服务的语言本身(的描述)同等的重要。C语言本身没有提供输入-输出或任何其它与外界交互(的方式),而依赖于一套标准过程。出版K&R的时候,C基本上被视为Unix的系统编程语言;尽管我们提供了库例程例子,该库例程的目标是容易转换到其它操作系统,但来自Unix的底层支持却是默认的。因此,X3J11委员会花了大量时间来设计和归档了一套库例程,它们必须在所有符合标准的实现中可用。

    按照标准过程的规则,X3J11委员会的当前活动限定于发布对已有标准的解释。然而,最初由Rex Jaeschke召集的叫NCEG(C数值扩展小组)的一个非正式组织,被正式接受为分组X3J11.1而且他们继续考虑对C的扩展。正如这个名字暗示的,许多可能的扩展打算使该语言更合适于数值的使用:例如,边界被动态检测的多维数组,加入处理IEEE算术的工具,以及使语言在具有向量或其它高级结构特征的机器上更有效。并非所有这些可能的扩展都是数值相关的;也包括一个结构字面值的符号。

    继承者

    C,甚至B,有一些直接的后代,尽管它们比不过Pascal的繁殖能力。有一个分支发展得很早。当1972年Steve Johnson在休假期间访问滑铁卢大学(University of Waterloo,加拿大)时,他携带了B。它在那儿的Honeywell机器上变得流行,而且产下了Eh和Zed(对“B之后是什么?”的加拿大答案)。当Johnson在1973年返回贝尔实验室时,他莫名其妙地发现,他带到加拿大的种子,该语言已经发展回到(自己的)老巢;甚至他自己的yacc程序已经由Alan Snyder用C重写了。

    C的更新的后代可能包括Concurrent C(并发C) [Gehani 89]、Objective C [Cox 86]、C* [Thinking 90],尤其是C++ [Stroustrup 86]。本语言也被广泛用作各种编译器的中间表示(基本上,用作可移植汇编语言),既用于如C++这样的直接后代,也用于Modula 3[Nelson 91]和Eiffel[Meyer 88]的这样的无关的语言。

    批评

    对比同类语言,最具C语言特色的两个思想是:数组和指针的关系,和声明语法以何种方式模拟表达式语法。它们也是最频繁受到抨击的特性之一,也常常成为初学者的绊脚石。对此两者,历史因素和错误加剧了它们的困难。最为重要的原因是C编译器对类型上的错误的容忍。从上述历史应该清楚,C由无类型语言进化而来。它不是作为拥有自己规则的全新的语言突然出现在其最初的用户和开发者面前;实际上,在语言发展中,我们不得不不断地改编已有的程序,并且要照顾已有代码。(后来,ANSI X3J11委员会在标准化C时面临同样的问题。)

    1977年甚至之后的编译器,没有对一些用法给出警告:在整数和指针间的赋值、使用错误类型的对象来引用结构体的成员。尽管在K&R第一版中给出的语言定义,在类型规则的处理上是相当(尽管不完全)自洽,但那本书允许现有的编译器不实施这些规则。此外,某些规则用于简化早期的转换而导致后期的混乱。例如,函数声明中的空方括号
     int f(a) int a[]; { ... }
    就是一个活化石,是声明指针的NB方式的遗迹;在C中,a仅在这个特殊的情况下才被被解释为一个指针。该表示法之所以残留,部分源于兼容性,部分是屈从这样的理论——它允许程序员告诉其读者这一意图,传递给f的指针产生于数组而不是引用简单的整型。不幸地是,它对学习者的迷惑与对读者的提示一样多。
    在K&R C中,为函数调用提供正确类型的参数是程序员的责任,而已有的编译器不检查类型一致性。原始语言在函数的类型签名中缺少参数类型,是一个重大缺陷,确实是一个需要X3J11委员会以最果敢和最痛苦的精神去修复(的玩意)。早期的设计说明(如果不是证明)了我对技术问题的逃避——特别是分离编译的源文件之间的交叉检查,和我对从无类型到类型语言迁移的含义的不透彻地把握。lint程序,前面提及过,尝试缓解这个问题:作为lint的功能之一,通过扫描一系列源文件、比较调用时和定义时的函数参数类型,lint检查整个程序的一致性和完备性。这种用于表达式的风格沿用于声明语句,所以这些名字可以声明为
        int *fp();
        int (*pf)();
    在更为装逼但仍现实的例子中,事情变得更糟糕:
        int *(*pfp)();
    是一个函数的指针,函数的返回值是一个整型指针(a pointer to a function returning a pointer to an integer)。有两个因素在起作用。最重要的(因素),C有相对丰富的方式(比如说,跟Pascal比较)进行类型描述。在和C一样的表达型——如Algol 68——语言中,声明语句描述对象同样难以理解,仅仅因为对象它们本身很复杂。第二个作用归因于语法细节。C的声明应该用一个"从内到外(inside-out)"的风格来阅读,该风格被很多人认为难以掌握[Anderson 80]。Sethi[Sethi 81]发现,许多嵌套的声明和表达式会较为简明,如果间接【indirection ,即*】运算符被当作后缀而非前缀时,但是到了(他指出的)那时,再做改变已经太晚了。【君生我未生,我生君已老 君恨我生迟,我恨君生早】[我生君未生,君生我已老。我离君天涯,君隔我海角]

    尽管它有些困难,我认为C的声明方式仍然是合理的,我也对此满意;这是一个有用的一致性原则。

    C的另一个特征,对数组的处理,尽管它确实很棒但是从实践的角度看,它【较第一点】更令人疑惑。虽然指针和数组间的关系不是通常(形式),(程序员)还是能学会的。而且,该语言在描述一些重要概念方面显示了强大能力,例如,仅仅使用几个基本规则和惯例,(描述了)在运行时长度可变的向量。特别是将字符串按照所有其他数组相同的机制处理,加上一个约定——空字符结束一个字符串。将C的方式与两个同时期的语言Algol68和Pascal[Jensen 74]比较,会很有趣。Algol 68中数组要么有固定边界,要么是“柔性的(flexible)”:对于语言定义和编译器都需要复杂的机制(支持)以适应柔性数组(而且并非所有编译器都完全实现了它们)。原始的Pascal只有固定尺寸的数组和串,这已被证明是有局限的[Kernighan 81]。后来它被部分修复(this was partially fixed),但是最终的语言没有广泛运用。

    C把串视为字符的数组,并约定以一个标记结束。除了用字符串文字进行初始化有一个特殊规则,字符串的语义完全包含在管理所有数组的一般性规则中,因此该语言比起其他将字符串当作独立数据类型的语言来,更易于描述和翻译。这一方式会增加一下成本:某些字符串操作比在其它设计中开销更大,因为应用代码或库例程必须时不时地查找串尾、因为没有可用的内置运算,也因为字符串的存储管理的责任压在了用户肩上。不管怎么说,C的操作符方式工作良好。

    另一方面,C对数组的处理,总体上(不仅仅是字符串)对优化和未来的扩展有不幸的影响。C程序中指针的盛行,不论是显式声明的还是由数组产生的,意味着优化必须很小心,而且必须谨慎地使用数据流技巧以达到满意的结果。高端的编译器能够懂得大多数可能改变的指针,但是一些重要的用法依然难以分析。例如以产生于数组的指针为参数的函数很难编译生成向量机上有效的代码,因为几乎不可能检测另一个参数指针与另一个参数是否有重迭的数据,或者外部可访问。更重要的是,C的定义非常明确地描述了数组的语义,因而将数组作为更原始对象处理、允许将它们作为整体来操作[这样的]改变和扩展,很难适合现在的语言。甚至声明和使用尺寸动态确定的多维数组的扩展,也曲折难行[MacDonald 89] [Ritchie 90],虽然它们能够使得用C编写数值例程库[变得]更为容易。因而,C通过一个一致而简单的机制,覆盖了实践中需要的字符串和数组的最重要的用法,但是将高效率实现和扩展的问题留了下来
    除了上面讨论的,当然,语言及其描述中还存在许多较小的瑕疵。也有一些不纠缠于细节的一般性批评被提出。主要是语言和它要求的基本环境基本上没有为编写大型系统提供帮助。命名结构仅提供了两个主要的级别:“external”(到处可见)和“internal”(在单个过程内)。可见性的一个中间级别(在单个文件内的数据和过程)与语言定义关系很微弱。因而,没有对模块化的直接支持,项目设计师将不得不使用自己的约定。
    类似,C本身两种存储生命期:“automatic”对象,当控制流程存在或低于过程时存在,“static”存在于程序的全部执行期。Off-stack,动态分配存储由一个库例程提供,而管理它们的责任落在程序员身上:C对自动垃圾回收不感冒

    成功原因?

    C的成功远远超出了早期的任何预期。哪些品质促进它得到广泛使用呢?
    毫无疑问,Unix本身的成功无疑是最重要的因素;它让这个语言可以被成千上万的人使用。另一方面,C在Unix中的使用,和它的到品种繁多的机器上的可移植性,对[Unix]系统的成功非常重要。而语言对其他环境的侵占揭示了更重要的价值。
    尽管对初学者甚至偶尔对老手而言,某些方面很难解,C不失为一个简单和小巧的语言,可被简单和小的编译器翻译。它的类型和操作充分依据真实机器所提供[的对应物],人们用它理解机器如何工作,学会编写时间和空间高效的程序也不困难。同时,语言充分抽象于机器细节,程序可移植性也可以达到。
    同样重要的是,C和它的主要库支持,总是保证能存在于一个真实环境中。它不是被设计用来孤立验证某一点,或作为一个例子,而是作为一个用来写有用程序的工具;它总是意味着同一个大型操作系统交互,并作为工具来创建更大工具。这一吝啬而务实的途径 影响了C所包含的东西:它覆盖了多数程序员的基本需要,但不试图提供太多东西。

    最后,从它的首次发布的、确实非正式和不完整的描述起,不论它经受何种变化,真实的C语言,正如数百万使用各种不同编译器的用户所见证的,比起那些同样流行的语言如Pascal和Fortra,它保持着显著的稳定性和一致性。虽然存在许多不同的C的方言——最显著的,较早的K&R和较新的标准C所描述的——但总体上,C比其它语言保持着更自由的属性扩展。或许最重要的扩展,是用于处理某些Intel处理器的特性的“far”和“near”指针限定符。尽管C原始设计中没有将可移植性作为一个主要目标,它在编写程序,也包含操作系统上取得了成功,从最小的个人计算机到最大的超级计算机。

    C诡异离奇、缺陷重重,却获得了巨大的成功。历史的机缘确有帮助,它显然满足了对足够有效以取代汇编的系统实现语言的需要,也足够抽象和流畅地描述算法,以及同各种各样的环境交互。

    致谢(略)
    参考
    [ANSI 89]American National Standards Institute, American National Standard for Information Systems—Programming Language C, X3.159-1989.
    [Anderson 80]B. Anderson, `Type syntax in the language C: an object lesson in syntactic innovation,' SIGPLAN Notices 15 (3), March, 1980, pp. 21-27.
    [Bell 72]J. R. Bell, `Threaded Code,' C. ACM 16 (6), pp. 370-372.
    [Canaday 69]R. H. Canaday and D. M. Ritchie, `Bell Laboratories BCPL,' AT&T Bell Laboratories internal memorandum, May, 1969.
    [Corbato 62]F. J. Corbato, M. Merwin-Dagget, R. C. Daley, `An Experimental Time-sharing System,' AFIPS Conf. Proc. SJCC, 1962, pp. 335-344.
    [Cox 86]B. J. Cox and A. J. Novobilski, Object-Oriented Programming: An Evolutionary Approach, Addison-Wesley: Reading, Mass., 1986. Second edition, 1991.
    [Gehani 89]N. H. Gehani and W. D. Roome, Concurrent C, Silicon Press: Summit, NJ, 1989.
    [Jensen 74]K. Jensen and N. Wirth, Pascal User Manual and Report, Springer-Verlag: New York, Heidelberg, Berlin. Second Edition, 1974.
    [Johnson 73]S. C. Johnson and B. W. Kernighan, `The Programming Language B,' Comp. Sci. Tech. Report #8, AT&T Bell Laboratories (January 1973).
    [Johnson 78a]S. C. Johnson and D. M. Ritchie, `Portability of C Programs and the UNIX System,' Bell Sys. Tech. J. 57 (6) (part 2), July-Aug, 1978.
    [Johnson 78b]S. C. Johnson, `A Portable Compiler: Theory and Practice,' Proc. 5th ACM POPL Symposium (January 1978).
    [Johnson 79a]S. C. Johnson, `Yet another compiler-compiler,' in Unix Programmer's Manual, Seventh Edition, Vol. 2A, M. D. McIlroy and B. W. Kernighan, eds. AT&T Bell Laboratories: Murray Hill, NJ, 1979.
    [Johnson 79b]S. C. Johnson, `Lint, a Program Checker,' in Unix Programmer's Manual, Seventh Edition, Vol. 2B, M. D. McIlroy and B. W. Kernighan, eds. AT&T Bell Laboratories: Murray Hill, NJ, 1979.
    [Kernighan 78]B. W. Kernighan and D. M. Ritchie, The C Programming Language, Prentice-Hall: Englewood Cliffs, NJ, 1978. Second edition, 1988.
    [Kernighan 81]B. W. Kernighan, `Why Pascal is not my favorite programming language,' Comp. Sci. Tech. Rep. #100, AT&T Bell Laboratories, 1981.
    [Lesk 73]M. E. Lesk, `A Portable I/O Package,' AT&T Bell Laboratories internal memorandum ca. 1973.
    [MacDonald 89]T. MacDonald, `Arrays of variable length,' J. C Lang. Trans 1 (3), Dec. 1989, pp. 215-233.
    [McClure 65]R. M. McClure, `TMG—A Syntax Directed Compiler,' Proc. 20th ACM National Conf. (1965), pp. 262-274.
    [McIlroy 60]M. D. McIlroy, `Macro Instruction Extensions of Compiler Languages,' C. ACM 3 (4), pp. 214-220.
    [McIlroy 79]M. D. McIlroy and B. W. Kernighan, eds, Unix Programmer's Manual, Seventh Edition, Vol. I, AT&T Bell Laboratories: Murray Hill, NJ, 1979.
    [Meyer 88]B. Meyer, Object-oriented Software Construction, Prentice-Hall: Englewood Cliffs, NJ, 1988.
    [Nelson 91]G. Nelson, Systems Programming with Modula-3, Prentice-Hall: Englewood Cliffs, NJ, 1991.
    [Organick 75]E. I. Organick, The Multics System: An Examination of its Structure, MIT Press: Cambridge, Mass., 1975.
    [Richards 67]M. Richards, `The BCPL Reference Manual,' MIT Project MAC Memorandum M-352, July 1967.
    [Richards 79]M. Richards and C. Whitbey-Strevens, BCPL: The Language and its Compiler, Cambridge Univ. Press: Cambridge, 1979.
    [Ritchie 78]D. M. Ritchie, `UNIX: A Retrospective,' Bell Sys. Tech. J. 57 (6) (part 2), July-Aug, 1978.
    [Ritchie 84]D. M. Ritchie, `The Evolution of the UNIX Time-sharing System,' AT&T Bell Labs. Tech. J. 63 (8) (part 2), Oct. 1984.
    [Ritchie 90]D. M. Ritchie, `Variable-size arrays in C,' J. C Lang. Trans. 2 (2), Sept. 1990, pp. 81-86.
    [Sethi 81]R. Sethi, `Uniform syntax for type expressions and declarators,' Softw. Prac. and Exp. 11 (6), June 1981, pp. 623-628.
    [Snyder 74]A. Snyder, A Portable Compiler for the Language C, MIT: Cambridge, Mass., 1974.
    [Stoy 72]J. E. Stoy and C. Strachey, `OS6—An experimental operating system for a small computer. Part I: General principles and structure,' Comp J. 15, (Aug. 1972), pp. 117-124.
    [Stroustrup 86]B. Stroustrup, The C++ Programming Language, Addison-Wesley: Reading, Mass., 1986. Second edition, 1991.
    [Thacker 79]C. P. Thacker, E. M. McCreight, B. W. Lampson, R. F. Sproull, D. R. Boggs, `Alto: A Personal Computer,' in Computer Structures: Principles and Examples, D. Sieworek, C. G. Bell, A. Newell, McGraw-Hill: New York, 1982.
    [Thinking 90]C* Programming Guide, Thinking Machines Corp.: Cambridge Mass., 1990.
    [Thompson 69]K. Thompson, `Bon—an Interactive Language,' undated AT&T Bell Laboratories internal memorandum (ca. 1969).
    [Wijngaarden 75]A. van Wijngaarden, B. J. Mailloux, J. E. Peck, C. H. Koster, M. Sintzoff, C. Lindsey, L. G. Meertens, R. G. Fisker, `Revised report on the algorithmic language Algol 68,' Acta Informatica 5, pp. 1-236.
    Copyright ? 2003 Lucent Technologies Inc. All rights reserved.

    展开全文
  • C语言的发展史 C语言之所以命名为C,是因为C语言源自Ken Thompson 发明的B语言,而B语言则源自BCPL语言. 1967年,剑桥大学的Martin Richards对CPL语言进行了简化,于是产生了BCPL(Basic Combined Programming Lauguage...
  • C语言的发展史及特点

    2020-02-19 19:26:54
    C语言发展史 1963年剑桥大学将ALG 60 发展成CPL语言 1967剑大(马丁理查德)对CPL语言简化,产生BCPL语言 1970美国贝尔实验室(肯汤姆森)将BCPL精华提炼 B语言 1973美国贝尔实验室(丹尼斯瑞切)在b语言基础上...
  • 02-C语言的发展史

    2020-06-01 21:15:59
    C语言问世之前,也有很多编程语言被开发出来,其中最早一门语言叫 Algol,是 上世纪五六十年代产生,它是真正第一门面向问题语言。但是这门语言离硬件比较远,所以 1963 年剑桥大学在 Algol 基础上...
  • C语言的发展史和特点

    2012-06-09 12:42:22
    C语言的发展过程 ——1972年诞生于美国贝尔实验室; ——1973年用于与汇编语言合写UNIX操作系统; ——1977年实现了可移植,逐步得到推广; ——1983年规范为 ANSI C,1987年进一步规范 87 ANSI C。 ...
  • 计算机发展史 1,电子管计算机 2,晶体管计算机 3,中小型规模集成电路计算机 4,大规模和超大规模集成电路计算机--微型计算机 5,计算机指具有人工智能的新一代计算机 编程语言的发展 1,冯络伊曼结构---计算机之父...
  • c语言的发展史及特点

    千次阅读 2014-07-22 11:44:57
    第1部分 发展史 1、
  • [01]C语言的发展史

    2015-11-07 14:24:06
    一、C语言形成契机1、剑桥大学和伦敦大学开发了CPL —>2、Martin Richard 开发了BCPL(Basic CPL) —>3、Ken Tompson(UNIX开发者) 开发了B语言—> 简单介绍一下:B是怎样语言 (1)B是没有类型语言,使用...
  • C语言的发展史(应该了解一下)

    千次阅读 2019-07-12 08:27:39
    发展历程: 我们来一个超级简化版本。 1969年之前所有操作系统都是用汇编语言编写。 1969年 肯.汤普逊在BCPL语言基础上 编写了B语言 用B语言写了UNIX操作系统内核代码。UNIX操作系统诞生于贝尔实验室。 ...
  • The Development of the C Language* Dennis M. Ritchie Bell Labs/Lucent Technologies ...不满足网上译文,yqj2065自己翻译一下。备用。【】是译注、补充。 概要 在1970s早期,C编程语言是作为新
  • c语言发展史

    2013-05-27 21:49:20
    描述了C语言的发展史,详细的描述了C语言的出现到成熟C语言的形成。
  • C语言发展史的点点滴滴

    千次阅读 多人点赞 2020-09-21 18:00:00
    作者:李彦锋,腾讯 IEG 运营开发工程师一直想写一篇关于C语言的文章,里面包含C语言的发展史、创始人等相关事迹。但是却迟迟未写,主要原因是因为:在我看来,这个语言太过于伟大、耀眼。作为...
  • C语言家族的发展史

    2011-11-24 14:28:36
    C语言家族的发展史,了解c语言家族的发展很好的文档。全面而细致,不乏幽默与调侃。
  • C语言发展史

    千次阅读 2016-09-24 23:12:59
    C语言发展史   1、第一个编程语言比现代计算机还早诞生。首先,这种语言是种编码(en:code)。于1801年发明提花织布机(或称甲卡提花织布机,英文:en:Jacquard loom),运用打孔卡上坑洞来代表缝纫织布机手臂...
  • c语言发展史-简介

    千次阅读 2017-12-16 00:27:38
    c语言发展史-简介 1早期发展  C语言最早由丹尼斯·里奇(Dennis Ritchie)为了在PDP-11电脑上运行Unix系统所设计出来编程语言,第一次发展在1969年到1973年之间。  C源于BCPL语言,后者由马丁·理察德...
  • 大家好,今天分享主题是:C语言发展史的点点滴滴。 任何一种新事物出现都不是来自于偶然,而是时代所驱使必然结果。 如果你问我:C语言有多伟大。那么,我可能会想一下,说:多伟大我不知道,但是我知道很伟大...
  • 浅谈C语言发展史

    2017-12-11 20:38:56
    C语言之所以命名为C,是因为 C语言源自Ken Thompson发明B语言,而 B语言则源自BCPL语言。   1967年,剑桥大学Martin Richards对CPL语言进行了简化,于是产生了BCPL(Basic Combined Programming Language)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 531
精华内容 212
关键字:

c语言的发展史

c语言 订阅