c语言 王者归来

C语言发展简史

 【起源】 语言最早的原型是 ALGOL 60 1963 年,剑桥大学将其发展成为 CPL(Combined Programing Language)。 1967 年,剑桥大学的 Matin Richards 对 CPL 语言进行了简化,产生了 BCPL 语言。 1970 年,美国贝尔实验室(Bell Labs)的 Ken Thompson 将 BCPL 进行了修改,并取名叫做 语言,意思是提取 CPL 的精华(Boiling CPL down to its basic good features)。并用 语言写了第一个 UNIX 系统。 1973 年,AT&T 贝尔实验室的 Dennis Ritchie(D.M.RITCHIE) 在 BCPL 和 语言的基础上设计出了一种新的语言,取 BCPL 中的第二个字母为名,这就是大名鼎鼎的 语言。随后不久,UNIX 的内核(Kernel) 和应用程序全部用 语言改写,从此,语言成为 UNIX 环境下使用最广泛的主流编程语言。 

K&R C】 1978 年,Dennis Ritchie 和 Brian Kernighan 合作推出了《The C Programming Language》的第一版(按照惯例,经典著作一定有简称,该著作简称为 K&R),书末的参考指南 (Reference Manual) 一节给出了当时 语言的完整定义,成为那时 语言事实上的标准,人们称之为 K&R C。从这一年以后,语言被移植到了各种机型上,并受到了广泛的支持,使 语言在当时的软件开发中几乎一统天下。 

C89 (ANSI C)】 随着 语言在多个领域的推广、应用,一些新的特性不断被各种编译器实现并添加进来。于是,建立一个新的“无歧义、于具体平台无关的 语言定义” 成为越来越重要的事情。1983 年,ASC X3(ANSI 属下专门负责信息技术标准化的机构,现已改名为 INCITS)成立了一个专门的技术委员会 J11(J11 是委员会编号,全称是 X3J11),负责起草关于 语言的标准草案。1989 年,草案被 ANSI 正式通过成为美国国家标准,被称为 C89 标准。 

C90 (ISO C)】 随后,《The C Programming Language》第二版开始出版发行,书中内容根据 ANSI C(C89)进行了更新。1990 年,在 ISO/IEC JTC1/SC22/WG14 (ISO/IEC 联合技术第 委员会第 22 分委员会第 14 工作组的努力下,ISO 批准了 ANSI C 成为国际标准。于是 ISO C(又称为 C90) 诞生了。除了标准文档在印刷编排上的某些细节不同外,ISO C(C90) 和 ANSI C(C89) 在技术上完全一样。 

C95】 之后,ISO 在 19941996 年 分别出版了 C90 的技术勘误文档,更正了一些印刷错误,并在1995 年通过了一份 C90 的技术补充,对 C90 进行了微小的扩充,经过扩充后的 ISO C 被称为 C95。 

C99】 1999 年,ANSI 和 ISO 又通过了最新版本的 语言标准和技术勘误文档,该标准被称为 C99 。这基本上是目前关于 语言的最新、最权威的定义了。 

    现在,各种 编译器都提供了 C89(C90) 的完整支持,对 C99 还只提供了部分支持,还有一部分提供了对某些 K&R C 风格的支持。 

 

/////////////////////////////////////////////////////

C语言的发展史

Dennis M. RitchieTjy平坦软件园

Bell Labs/Lucent TechnologiesTjy平坦软件园

Murray Hill, NJ 07974 USATjy平坦软件园

[email protected] 

概要

C语言作为最初的Unix操作系统的系统实现语言,在1970年早期诞生。它以无类型的B语言为基础,形成了一个类型结构;它在小型机上被发明,作为一个工具,以改进贫乏的编程环境。在今天,它已经成为一种占统治地位的语言。本文研究它的发展。 Tjy平坦软件园

简介

版权提示:版权所有1993计算机协会公司。此电子版由作者授权发表。有关出版事宜,请联系ACM或作者。本文被用于一九九三年四月,在马萨诸塞州剑桥的第二次编程语言历史会议上的演讲。 Tjy平坦软件园

之后被收录进会议记录:编程语言历史,第二版。Thomas J. Bergin, Jr. and Richard G. Gibson, Jr. ACM Press (New York) and Addison-Wesley (Reading, Mass), 1996; ISBN 0-201-89502-1. 

本文是关于C程序设计语言的发展、它所受到的影响以及它诞生的条件。为简洁起见,我略过了对C本身完整的描述、它的起源B[Johnson 73]及更上一代BCPL[Richards 79],相反集中关注每一种语言的典型特性,以及他们如何发展变化。 Tjy平坦软件园

C1969——1973年间与Unix操作系统同时诞生;最富创造性的时期是1972年。另一次大的变化发生在19771979年间,当Unix系统的可移植性得到证明时。在后一段时期的中间,这个语言的第一个被广为传播的描述出现了:C程序设计语言,常常被称为白皮书或K&R[Kernighan 78]。最后,在1980年代中期,它被ANSI X3J11委员会正式标准化,作了进一步修改。直到1980年代早期,尽管编译器已在多种机器结构及操作系统上出现,这个语言几乎与Unix特别密切关联;更近一些,它的使用传播得更广,并且在今天它几乎是计算机行业被使用最多的语言。 Tjy平坦软件园

历史:环境

贝尔电话实验室的计算机系统研究在1960代年晚期是乱糟糟的[Ritchie 78] [Ritchie 84]。贝尔电话实验室公司正从他和麻省理工学院、通用电气公司的合作项目Multics[Organick 78]撤离。到1969年,贝尔实验室管理层和研究人员认为,Multics项目不能按期完成并且代价高昂。在GE-645 Multics机器被撤走之前,Ken Thompson领导一个非正式小组,开始一些其它的研究。 Tjy平坦软件园

Thompson希望按自己的设计,使用一切有效的方式,创造一个适当的计算环境。他的计划,回想起来是清晰的。组合Multics中的许多创新特征,包括一个作为控制场所的进程的清晰概念、一个树结构文件系统、一个作为用户级程序的命令解释器、文本文件的简单表示和访问设备的通用化。他们排除其余特性,比如对内存和文件的统一访问。开始,他与我们其余人推迟了Multics中的另一个先锋性(但非原创)特征,即只使用高级语言来编写。我对Multics实现所用的语言PL/I,并无兴趣,但我们还使用其他语言,包括BCPL,我们对于不能利用汇编之上的高级语言进行编程的优点,比如容易编写、易于理解,感到遗憾。当时我们并未特别注重可移植性;到后来才有了这方面的兴趣。 Tjy平坦软件园

Thompson面临的是那个时代古怪和难缠的硬件:DEC PDP-7,他在1968年开始使用时,只有8K容量的16位内存,并且没有可用的软件。当时他希望使用高级语言,但还是用PDP-7汇编编写了最初的Unix系统。开始,他并未在PDP-7上编码,相反使用一套GE-635机器上,用于GEMAP汇编器的宏。一个后期处理器生成PDP-7可读的纸带。 Tjy平坦软件园

这些纸带从GE机器传送到PDP-7进行测试,直到一个原始的Unix内核、一个编辑器、一个汇编器、一个简单的shell(命令解析器),和其它工具(像Unix rm, cat, cp命令)被完成。此后,这个操作系统可以自我支撑:可以编写、测试程序勿需借助纸带,并且程序开发可以在PDP-7上继续进行。 Tjy平坦软件园

ThompsonPDP-7汇编器在简明性上甚至优于DEC的;它对表达式求值并得到对应的数据位。没有库、装载器或链接器:程序的全部源文件被送给汇编器,输出文件——有一个固定名字——产生后被直接执行(这个名字,a.out,解释了一点Unix的渊源;它是汇编器的输出。甚至在系统有了链接器和显式指定另一个名字的方式之后,它仍被保留作为编译的默认可执行文件)。 Tjy平坦软件园

Unix首次在PDP-7运行后不久,Doug McIlroy1969年创造了新系统的第一个新语言:一个McClureTMG[McClure 65]实现。TMG是一种编写编译器(更普通来说,TransMoGrifiers)的语言,通过在一个混合过程元素,上下文无关的语法标记的自顶而下,递归降解的风格。McIlroyBob Morris使用TMGMultics编写了早期的PL/I编译器。 Tjy平坦软件园

为了挑战McIlroy重新生成TMG的技巧,Thmopson决定Unix——当时可能还没有取这个名字——需要一种系统编程语言。在很快用Fortran尝试一番后,相反,他创造了一种他自己的语言,他命名为BB可以认为是没有类型的C。更准确,它是被挤进了8K字节内存,经过Thompson大脑过滤的BCPL。它的名字最有可能表示BCPL的缩写,尽管另一种理论认为它继承自Bon[Thompson 69],一个ThompsonMultics的那些日子创造的不相关的语言。Bon可能是以他妻子Bonnie的名字,或者(根据它的手册中的一个encyclopedia引用)以一种具有咕隆咕隆发音的神奇仪式的宗教命名的。 Tjy平坦软件园

起源:语言

BCPLMartin Richards1960年代中期在访问麻省理工学院时设计,在1970年代早期被用在几个有趣的项目中,其中包括牛津大学的OS6操作系统[Stoy 72],和施乐公司PARC研究中心创造性的Alto上的部分工作[Thacker 79]。因为Richards工作过的麻省理工学院的CTSS系统[Corbato 62]被用于Multics开发,我们也熟悉该语言。最初的BCPL编译器被Rudd Canaday和贝尔实验室的一些人们迁移到MulticsGE-635 GECOS系统[Canaday 69];在Multics的生命在贝尔实验室的最后痛苦挣扎中,它很快成了那些以后参与Unix的人们选择的语言。 Tjy平坦软件园

BCPL, BC全都严格符合以FortranAlgol 60代表的传统过程类型语言。它们都面向系统编程、小、定义简洁,以及可被简单编译器翻译。它们接近机器,它们引入的抽象以传统计算机提供的具体数据类型和操作为基础,它们依赖于输入输出库例程,与操作系统的其它交互。尽管并未成功,它们还使用库程序指定其他有趣的控制结构,如协程和过程关闭。同时,它们的抽象层次足够高,足够用心的话,能达到机器间的可移植性。 Tjy平坦软件园

BCPL, BC在语法上差异众多,粗略地说,它们是相似的。程序由全局声明和函数(过程)声明组成。BCPL中的过程能够嵌套,但不能引用包含过程中的非静态对象。BC避免了这个限制,通过强加一个更严格限制:完全没有嵌套过程。每一种语言(除了早期版本B)都认可分离编译,以及提供了包含指定文件文本的方式。 Tjy平坦软件园

BCPL中的几个语法和词法机制是优雅和常见的,甚于BC中的那些。例如,BCPL的过程和数据声明有更一致的结构,并且它提供了一套更完整的循环构造。尽管BCPL程序在概念上是由未被间隔的字符流,聪明的规则允许语句后的行分界处的大多数分号被忽略。BC忽略了这种便利,并以分号来结束大多数语句。不管这些差异,BCPL的大多数语句和操作符直接对应BC中的相应语句和操作符。 Tjy平坦软件园

BCPLB之间的一些结构化的差异源于介质存储的限制。比如,BCPL声明采用这样的形式 Tjy平坦软件园

    let P1 be command    and P2 be command    and P3 be command     ...此处的命令表示的程序文本包含完整过程。关联的子声明同时出现,所以名字P3guochengP1内可见。相似地,BCPL能在一个求得一个值的表达式里包含一组声明和语句,例如 Tjy平坦软件园

    E1 := valof ( declarations ; commands ; resultis E2 ) + 1BCPL编译器可以容易地处理此类构造,在产生输出前,通过存储和分析内存中一个完整程序解析过的表示。B编译器的存储限制要求一个一步技术,通过它尽可能快生成输出,语法上的重新设计,令这种可能迈进了C。 Tjy平坦软件园

BCPL中一些不令人满意的地方归因于它的技术问题,在B的设计中它们被有意识的避免了。例如,BCPL使用一个“全局向量”(global vector)机制以在分离编译的程序间通信。在这种模式中,程序员使用一个全局向量的数值偏移量,显式关联每个外部可见过程和数据对象的名字。链接使用这些数值偏移量,在被编译过的代码上完成。B起初坚持,整个程序一次性全部传递给编译器,来规避这个麻烦。B的后期实现,和C的全部实现,使用一个传统的链接器,来解决出现在分离编译文件中的外部名字,而不是把指定偏移量的负担推给程序员。 Tjy平坦软件园

BCPLB的转换中引入的其它变化,大概是因为风格的缘故,一些仍是有争议的,例如赋值使用单个字符=代替:=。类似地,B使用/**/来括起注释,而B使用//注释直至行末的文本。这显然是从PL/I继承来的。(C++重新启用了BCPL的注释惯例。) Fortran影响了声明的语法:B的声明以一个auto, static这样的类型指定符开始,跟着一列名字,C不仅遵循这种风格,还把它的类型关键字,加入这种声明的开始处。 Tjy平坦软件园

Richards的书中文档化的BCPLB之间的差别,并非都是经过深思熟虑的;我们是从一个BCPL[Richards 79]的早期版本开始工作的。例如,用于跳离switchon语句的endcase在我们1960年代开始学习该语言时,并没有出现,所以BC中重复出现的,用于跳离switch语句的关键字break,乃是一种背离的发展,而不是清醒的改变。 Tjy平坦软件园

对比B产生过程中发生的普遍的语法变化,BCPL的核心语义内容——类型结构和表达式求值——保持不变。它们两种语言都是无类型的,或更恰当地说有一种单一的数据类型,“字”(word)或“单元”(cell),一个固定长度的位模式。这些语言中的内存由此类单元的线形数组组成,每一个单元的内容的含义与应用的运算相关。例如,求和运算符使用机器的整数加法指令,简单相加其运算对象,其它算术运算同样不清楚它们运算对象的含义。因为内存是一个线形数组,只可能解析单元的值为该数组的索引,并且BCPL为这个目的提供一个运算符。在最初的语言中,它被拼写为rv,后来为!,但是B使用一元*。因此,如果p是单元,包含另一个单元的索引(其地址,或指向的指针),*p引用被指向单元的内容,作为表达式的值或赋值对象。 Tjy平坦软件园

因为指针在BCPLB中只不过是整型内存数组的索引,对它们进行算术运算是有意义的:如果p是一个单元的地址,那么p+1是下一个单元的地址。这种约定是两种语言中数组语义的基础。在BCPL中,一个人这样写 Tjy平坦软件园

    let V = vec 10或在B中, Tjy平坦软件园

    auto V[10];效果是一样的:分配了一个名字为V的单元,然后保留另一组10个连续单元,它们中第一个的内村索引,被存放在V中。按照一般的规则,在B中的表达式 Tjy平坦软件园

    *(V+i)Vi相加,并指向V后第i个位置。BCPLB都增加了特别的符号,使这种对数组的访问更简洁;在B中的等价表达式是 Tjy平坦软件园

    V[i]BCPL中是 Tjy平坦软件园

    V!i这种引用数组的方法甚至在当时仍是不常见的;C后来同化它为一种更不常规的方式。 Tjy平坦软件园

BCPLBC都没有强烈支持字符数据;每一个都把字符串当作整型数组,并通过一些惯例提供了一些一般规则。字符串字面值在BCPLB中表示一个使用串内字符初始化的静态区的地址,被包装成单元。在BCPL中,第一个被包装的单元包含串所拥有的字符个数;在B中,没有此计数,字符串以一个特别的字符终结,在B中杯拼写为“*e”。这个改变部分是为了避免把计数值放在一个8位或9位槽(slot)产生的串长度限制,部分是因为维护这个计数,从我们的经验看来,不如使用一个终结符方便。 Tjy平坦软件园

BCPL,串中每个字符的使用,是通过被展开为另一个数组,一个字符对应一个单元,然后进行再次包装;B提供了对应的例程,但人们更多地使用,另外的访问或替换一个串内字符的库函数。 Tjy平坦软件园

更多历史

TMG版本B工作后,Thompson利用B重写了B(编译器)(一个bootstrapping步骤)。在开发中,他不断与内存限制作斗争:每次语言版本使编译器膨胀令内存几乎不够使用,但每次重写利用语言特征的优点,减少了它的尺寸。例如,B引入通用赋值运算符,使用x=+y来把y加入x。这个符号经过McIlroy引自Algol 68[Wijngaarden 75],他将它合并到他实现的一个TMG版本。(在B和早期C,该运算符被拼作=+而不是+=;这个由B的词法分析的第一种形式的迷惑捷径导致的错误,在1967年被修复。) Tjy平坦软件园

Thompson通过发明自增++和自减--运算符,走出了更深远的一步;它们的前缀或后缀位置决定变更是发生在计算运算对象值之前或之后。它们没有出现在B的最早版本中,而是随后才出现的。人们经常猜测,它们被创造是为了使用,CUnix在其上首次流行的DEC PDP-11提供的自增和自减地址模式。这在历史上来说是不可能的,因为B被发明的时候还没有PDP-11PDP-7有一些“自增”内存单元,使用这种特性,一个间接内存引用通过它们来自增单元。这些特征可能提示Thompson创造了那些自增运算符;他把前缀和后缀一般化。甚至,自增单元没有被直接用于实现这些运算符,并且这种创新一个更强烈的动机可能是,他发觉++x的翻译在尺寸上小于x=x+1。 Tjy平坦软件园

PDP-7上的B编译器不产生机器指令,而是一个由编译器输出组成代码段地址序列,执行基本运算的解释模式的threaded代码[Bell 72]。这些操作——特别对B——典型地运行在一个简单堆栈机器上。 Tjy平坦软件园

PDP-7Unix系统上,除了B本身只有几个东西是B写的,因为这个机器太小和太慢,除了试验而不能做更多事情;完全用B重写操作系统和其它应用程序,是看起来不可行的代价高昂的动作。Thompson在某些地方,通过提供一个利用换页解释器代码和数据,允许解释超过8K字节的程序的“虚拟B”编译器,来释放地址空间,但它对通用程序来说太慢以致不实用。尽管如此,一些用B写的工具还是出现了,包括一个早期版本的,Unix用户熟悉的可变精度计算器dc[McIlroy 79]。我做的最有雄心壮志的工作,是一个把B翻译为GE-635机器指令而非threaded 代码的真正的交叉编译器。它是一个精巧的绝技:一个用本身语言写的,生成在一个,在有4k字长用户地址空间的18位机器上运行的36位大型机代码,完全的B编译器。这个项目能实现,仅仅是因为B的简单性和它的运行时系统。 Tjy平坦软件园

尽管我们抱有关于实现一个那时,像Fortran, PL/IAlgol 68的主要语言的偶然想法。这样的项目对我们的显得绝望的大:需要更简单和小的工具。所有这些语言都影响我们的工作,但是凭我们自己之力来做这些事情则更有趣。 Tjy平坦软件园

1970年时,我们看起来能在Unix项目上,获得一个新的DEC PDP-11。处理器是DEC递交的第一批产品,三个月后,磁盘才到达。通过threaded技巧,使B程序在其上运行只需要为运算符重写代码段,和一个我用B写的简单的汇编器。很快,dc成了在其它操作系统之前,第一个在我们的PDP-11上被测试的有趣的程序。几乎非常快,但仍需等待磁盘,ThompsonPDP-11汇编语言,重写了Unix内核和一些基本命令。最早的PDP-11上的Unix把机器上24K内存中的12K给操作系统,一个很小的空间给用户程序,其余的作为RAM磁盘。这一版本仅是用于测试,而不是实际的工作;这个机器通过枚举关闭的,knight的不同尺寸象棋板的路程,来标记时间。在磁盘到达后,我们把汇编语言转换为PDP-11上的方言,和移植一些B程序,很快移植到它上面去。 Tjy平坦软件园

1971年时,我们的微型计算机中心开始有了用户。我们都希望更容易编写有趣的软件。使用汇编显得沉闷,B不管它的性能问题,已经有了一个小的包含有用服务例程的库,并且被用于越来越多的新程序。这段时期的最著名的成果,是Steve Johnsonyacc分析——生成器[Johnson 79a]的第一个版本。 Tjy平坦软件园

B的问题

我们第一次使用BCPL然后是B的机器,是按字寻址的,这些语言的单一数据类型,“单元”,能恰当与硬件机器字互相换算。PDP-11的出现暴露了B的语义模型的一些不足。首先,它从BCPL继承的几乎未作改变的字符处理机制是笨拙的:使用库方法把包装的字符串展开到单个的单元,然后再次包装,或者访问或替换单个字符,在一个面向字节的机器上,开始变得笨拙,甚至愚蠢。 Tjy平坦软件园

其次,尽管最初的PDP-11没有提供浮点算术运算,制造商承诺将很快提供。浮点运算通过定义特别的运算符,被添加到我们的MulticsGCOSB编译器,但是这种机制仅在相应的机器上才可能,单个字长足够包含一个浮点数;这在16PDP-11上是不成立的。 Tjy平坦软件园

最后,BBCPL模型在处理指针时,暗中会做得更多:语言规则,通过定义一个指针作为字数组的索引,强迫指针被表示为字索引。每个指针引用生成一个运行时,从指针到硬件要求的字节地址的度量转换。 Tjy平坦软件园

因为这些理由,看起来需要一个类型模式来处理字符和字节寻址,以及为即将到来的浮点硬件作准备。其它问题,特别是类型安全性和接口检查,看起来并没有变得像以后那样重要。 Tjy平坦软件园

除了语言本身的问题,B编译器的threaded代码技术得到的程序,比他们对应的汇编语言版本慢很多,以至我们对用B纪录操作系统或它的中心工具的可能性打折扣。 Tjy平坦软件园

1971年时,我开始通过添加一个字符类型,并重写它的编译器以生成PDP-11机器指令而非threaded代码,来扩展B语言。因此从BC的转换,与创造一个同汇编语言竞争,能产生足够快和小的程序的编译器,是同时进行的。我称这个轻微扩展的语言为NB,表示“新B”(new B)。 Tjy平坦软件园

C萌芽

NB只存在了很短时间,以至没有编写一个它的完整描述。它提供类型intchar,它们的数组,指向它们的指针,用典型风格声明如下 Tjy平坦软件园

    int i, j;    char c, d;    int iarray[10];    int ipoint[];    char carray[10];    char cpoint[];数组的语义与在BBCPL中保持一样:iarraycarray的声明产生的单元,被动态初始化为分别指向十个整数和字符序列中的第一个的值。ipointercpointer的声明省略了尺寸,以表明没有存储被自动分配。在过程内部,语言对指针的解释与数组变量是一样的:一个指针声明产生一个单元与数组声明的区别仅在,程序员被期望给它赋值,而不是让编译器分配空间和初始化单元。 Tjy平坦软件园

值存储在数组的单元中,指针是按字节计算的,对应存储区的机器地址。因此通过指针间接引用,不意味着比按比例缩放指针从字到字节的偏移,有更多运行时开销。另一方面,对应数组取下标的机器代码和指针算术依赖于数组和指针的类型:计算iarray[i]ipointer+i表示按比例缩放加数i与所指向对象的尺寸。 Tjy平坦软件园

这些语义表示一个来自B的容易转换,我在它们上面实验了几个月。当我尝试扩展类型符号,特别是添加结构化(纪录)类型时,问题变得明显。结构看起来,应该以一种直接的方式影射到机器的内存,但一个结构包含一个数组,没有合适的地方隐藏包含数组基地址的指针,也没有方便的方式安排被初始化的对象。例如,早期unix系统的目录条目,在C可以被描述为 Tjy平坦软件园

    struct {        int  inumber;        char name[14];    };我希望结构不能仅仅是体现抽象对象的特征,也要描述可能从目录读到的位集合。编译器能在哪里隐藏指向语义要求的name的指针呢?即使结构被想象的更抽象,指针的空间也能以某种方式隐藏,我如何处理在分配一个,可能是一个结构包含数组再包含结构到任意深度的复杂对象时,完全初始化这些指针的技术问题? Tjy平坦软件园

这个解决方案形成了一个,在无类型BCPL和类型化C之间进化链中的重要飞跃。它移除了指针在内存的具体化。相反促成数组名出现在表达式中时生成指针。C语言的这个规则一直存在至今,就是数组类型的值当出现在表达式中时,被转换成指向组成数组的对象中的第一个对象的指针。 Tjy平坦软件园

这个发明使现存的B代码能继续工作,不管下层语言语义的改变。仅有几个程序为了调整它的起点,把新值赋给数组名——在BBCPL中是可能的,在C中无意义——都被很容易修改。更重要的是,新语言保持一致性和对数组有效的(如果并非常见)可解释性,开辟了通往复杂类型结构的道路。 Tjy平坦软件园

第二个创新,极力明显地把C与它的前辈们区分开来,那就是更完整的类型结构,尤其是在声明语法中的表达式,NB提供基本的类型intchar,它们的数组,指向它们的指针,但没有更进一步的组合。通用化也被要求:给定一个任意类型对象,描述一个包含它们的新对象,从一个函数求得它,或一个指向它的指针,都是可能的。 Tjy平坦软件园

对每一个此类复合类对象,已经有了一种讨论下层对象的方式:索引数组,调用函数,间接引用指针。类比推理导致了一种名字镜像声明语法,名字特征出现的表达式语法,因此, Tjy平坦软件园

    int i, *pi, **ppi;声明一个整数,一个指向整数的指针,一个指向指向整数的指针的指针。这些声明的语法反映i*pi**pi用于表达式时,都得到一个整数类型。类似地, Tjy平坦软件园

    int f(), *f(), (*f)();声明一个返回整型值的函数,一个返回整型指针的函数,一个指向返回整型函数的指针; Tjy平坦软件园

    int *api[10], (*pai)[10];声明一个整型指针数组,一指向整型数组的指针。在所有这些情况中,一个变量的声明类似它在表达式中的用法,它的类型是在声明中,置于开头的那个。 Tjy平坦软件园

C语言采用类型组合模式归功于Algol 68,尽管它或许没有以Algol追随者认可的模式出现。我从Algol获取的主要概念,是一个基于原子类型的类型结构(包括结构),组合为数组,

你可能感兴趣的:(c,unix,汇编,语言,fortran,编译器)