1C的标准化过程C语言自诞生到现在,期间经历了多次标准化过程,主要分成以下几个阶段:1.1TraditionalC此时的C语言还没有标准化,来自“CProgrammingLanguage,FirstEdition,byBrianW.Kernighan,DennisM.Ritchie.PrenticeHallPTR1978”的C描述可算作“正式”的标准,所以此时的C也称为“K&R”C。期间C语言一直不断的发生细微的变化,各编译器厂商也有自己的扩展,这个过程一直持续到20世纪80年代末。1.2C89考虑到标准化的重要,ANSI(AmericanNationalStandardsInstitute)制定了第一个C标准,在1989年被正式采用(AmericanNationalStandardX3.159-1989),故称为C89,也称为ANSIC。该标准随后被ISO采纳,成为国际标准(ISO/IEC9899:1990)。C89的主要改动:•定义了C标准库;•新的预处理命令和特性;•函数原型(prototype);•新关键字:const、volatile、signed;•宽字符、宽字符串和多字节字符;•转化规则、声明(declaration)、类型检查的改变。1.3C95这是对C89的一个修订和扩充,称为“C89withAmendment1”或C95,严格说来并不是一个真正的标准。C95的主要改动:•3个新标准头文件:iso646.h、wctype.h、wchar.h;•一些新的标记(token)和宏(macro);•一些新的printf/scanf系列函数的格式符;•增加了大量的宽字符和多字节字符函数、常数和类型。1.4C99这是目前最新的标准,由ISO制定于1999年(ISO/IEC9899:1999),故称为C99。C99的主要改动:•复数(complex);•整数(integer)类型扩展;•变长数组;•Boolean类型;•非英语字符集的更好支持;•浮点类型的更好支持;•提供全部类型的数学函数;•C++风格注释(//)。2C标准文档2.1C99这是一个pdf文件:c99.pdf。2.2C89C99已经替代C89成为标准,所以C89文档已经很难找了。下面是书籍“CProgrammingLanguage,SecondEdition,byBrianW.Kernighan,DennisM.Ritchie.PrenticeHallPTR(April1,1988),0131103628.”附录A的一份拷贝,在此作为C89标准以供需要时查阅。同时也提供中文版本,内容来自该书对应的中译版“《C程序设计语言》,徐宝文等译,机械工业出版社出版,ISBN7111075897”。文档仅供个人参考使用(建议以英文版为主):英文版中文版为方便起见,提供一份标点符号中英对照表,希望有用:标点符号中英对照表。3C标准的选择选择标准依赖于编译器的支持和对可移植性的要求。C99是当前的标准,但它仍未得到广泛支持,虽然标准发布已经多年。C99对C89(C95)的改动非常大,如果编写C99的代码,那么可移植性必然受到限制。此外,个人认为C99的一些新特性在大多数程序设计中并不是必须的。C89(包括C95)是目前使用最广泛的,并得到所有主流编译器的支持。TraditionalC现在只会在一些非常老的代码中才能见到了,除非你在维护旧代码,否则不应该再使用它。所以,个人觉得当前还是以C89(包括C95)标准为主。1引言本手册描述的c语言是1988年10月31日提交给ANSI的草案,批准号为“美国国家信息系统标准―C程序设计语言,X3.159-1989”。尽管我们已非常小心,以便这个手册的介绍可以信赖,但它毕竞不是标准本身,而是对标准的一个解释。这个手册的安排基本与标准相似,也与本书的第1版相似,但是对细节的组织是不同的。本手册给出的语法与标难是一样的,只是有少量产生式有所修改,词法元素和预处理器的定义也非形式化。注释部分说明了ANSI标准C与本书第1版介绍的或其他编译器所支持的语言的细微差别。2词法规则一个程序由存储在文件中的一个或多个翻译单元织成,程序的翻译分几个阶段完成,这将在12节中介绍。翻译的第一阶段完成低级的词法转换,执行由字符#开始的行所引入的指令,井进行宏定义和宏扩展。当预处理(将在12节中介绍)完成后,程序就被归约成一个单词序列。2.1单词共有6类单词;标识符、关键字、常量、字符串字面值、运算符和其他分隔符。空格、横向和纵向制表符.换行符、换页符和注解(合称空白符)在程序中仅用来分隔单词,因此将被略过。空白符用来分开相邻的标识符、关键字和常量。如果到某一字符为止的输人流被分成若干单词.那么下一个单词就是可能组成单词的最长的字符串。2.2注解注解以字符/*开始,以*/结束。注解不可以嵌套,也不可以出现在字符串中或字符字面值中。2.3标识符标识符是一个字母和数字的序列,其第一个字符必须是―个字母,下划线_也被当做字母。大写和小写字母组成的标识符是不同的。标识符可以任意长。对于内部标识符,至少前31个字母是有意义的,在某些实现中这个值可以更大。内部标识符包括预处理的宏名和其他没有外部连接(见11.2节)的名字。有外部连接的标识符的限制要多一些,其实现可能只认为前6个字符是有意义的.而且有可能忽略大小写的不同。2.4关键字以下标识符被保留为关键字,它们不能用做别的用途:autodoubleintstructbreakelselongswitchcaseenumregistertypedefcharexternreturnunionconstfloatshortunsignedcontinueforsignedvoiddefaultgotosizeofvolatiledoifstaticwhile有些实现还把单词fortran和asm保留为关键宇。•关健字const、signed和volatile是ANSI标准中新增加的,enum和void是第1版后新增如的,entry曾经被保留为关键字,但现在已不是了。2.5常量共有几种类型的常量,它们每一种都有一个数据类型,基本类型将在4.2节讨论。常量:整数常量字符常量浮点常量枚举常量2.5.1整数常量整数常量由一串数字序列组成。如果它以0(数字0)开始,那么是八进制数.否则就是十进制数。八进制常量不包括数字8和9。以0x和0X(数字0)开始的数字序列是十六进制数,十六进制数包含到从a~f或从A~F的字母,它们分别表示10~15。一个整数常量可以以宁母u或U为后缀,表示它是一个无符号数;也可以以字母l或L为后缀,表示它是一个长整数。一个整数常量的类型依赖于它的形式、值和后缀(类型的讨论见4节)。如果它没有后缀且是十进制的,那么它的类型很可能是int、longint或unsignedlongint。如果它没有后缀且是八进制的或十六进制的,那么它的类型很可能是int、unsignedint、longint、unsignedlongint。如果它的后缀为u或U,那么它的类型很可能是unsignedint或unsignedlongint。如果它的后缀为l或L,那么它的类型很可能是longint或unsignedlongint。•整数常量类型的确定比第1版要详细得多;在第1版中,大的整数常量仅被看做是long类型的。U后缀是新增加的。2.5.2字符常量字符常量是由单引号括住的一个或多个字符的序列,如'x'。单字符常量的值是执行时机器的字符集中的此字符的数值,多字符常量的值由实现定义。字符常量不包括字符'和换行符,为了表示它们和某些其他的字符,可以使用以下的转义序列(换码序列):newlineNL(LF)\n换行符horizontaltabHT\t横向制表符verticaltabVT\v纵向制表符backspaceBS\b回退符carriagereturnCR\r回车符formfeedFF\f换页符audiblealertBEL\a响铃符backslash\\\反斜线questionmark?\?问号singlequote'\'单引号doublequote\双引号octalnumberooo\ooo八进制数hexnumberhh\xhh十六进制数转义序列\ooo由反斜杠后跟1、2或3个用来确定对应字符的值的八进制数字组成。一个普通的例子是\0(其后没有数字),它表示字符NUL。转义序列\xhh由反斜杠开始,后跟x,其后是十六进制数字,用来确定对应字符的值。数字的个数没有限制,但如果对应的字符的值超过最大的字符的值,那么该行为是未定义的。对于八进制或十六进制转义字符,如果实现中将类型char看做是有符号的,那么将对字符值进行符号扩展,就好像它被强制转换为char类型一样。如果\后面的字符不是以上所说明的,那么其行为是未定义的。在C语言的某些实现中,有一个扩展的字符集,扩展的部分不能用char类型表示。在该扩展集中,常量是由一个前导L开始(如;L'x'),叫做宽字符常量。这种常量的类型为wchar_t。这是一个整数类型,定义在标准头文件stddef.h中。与通常的字符常量一样.可以使用八进制和十六进制的转义序列;但是,如果值超过wchar_t可以表示的范围,那么结果是未定义的。•某些转义序列是新增加的,特别是十六进制字符的表示。扩展的字符也是新增加的。通常美国和西欧所用的字符集可以用char编码;增加wchar_t的主要意图是为了表示亚洲的语言。2.5.3浮点常量一个浮点常量包含有一个整数部分、一个小数点、一个小数部分、一个e或E,一个可选的有符号整数类型的指数和一个可选的表示类型的后缀(即f、F、l或L)。整数和小数部分均由数字序列组成。可以没有整数部分或小数部分(但不能二者都没有)。小数点部分或者e和指数部分可以没有(但不能二者都没有)。浮点常量的类型由后缀确定,F或f后缀表示它float类型;1或L后缀表明它是longdouble类型;若没有后缀则是double类型。•浮点常量的后缀是新增加的。2.5.4枚举常量定义为枚举符的标识符是int类型的常量(见8.4节)。2.6字符串字面值字符串字面值也叫字符毒常量,是由双引号括起来的一个字符序列,如...。字符串的类型为“字符数组”,存储类为static(见4节),由给定的字符来初始化。相同的字符串字面值是否看做是不同的取决于具体的实现。如果程序试图改变字符串字面值,那么该行为是未定义的。我们可以把相邻的字符串字面值连接为一个单一的字符串。任何连接之后,一个空字节\0被加到字符串的后面以使程序在扫描字符串时知道已到达字符串的末尾。字符串字面值不包含换行符和双引号符;但可以用与字符常量相同的转义序列来表示它们。与字符常量一样,扩展字符集中字符串字面值以前导字符L表示,如L...。宽字符的字符串字面值的类型为wchar_t的数组,将普通字符串和宽字符的字符串字面值进行连接是未定义的。•如下说明都是ANSIC标准中新增加的:字符串字面值不必相区别、紫止修改字符串字面值以及相邻字符串字面值的连接。宽字符的字符串字面值也是新增加的。3语法符号在本手册用到的语法符号中,语法类别由斜体字表示。字面值单词和字符以打字机字体表示。可选类别通常列在不同的行中,但在少数情况下,一长串短的可选项可以表示在一行中,以短语“之一”(oneof)标识。任选的终结符或非终结符带有下标“opt”。例如:表达式opt表示一个括在花括号中的任选的表达式。语法概要在13节中给出。•与本书第1版给出的语法不同,本书给出的语法使表达式运算符的优先级和结合性是显式的。4标识符的含义标识符也叫名字,可以指代很多实体:函数、结构标记、联合和枚举,结构或联合的成员,枚举常量,类型定义名字以及对象。一个对象,有时也称为变量,是一个存储区域。它的解释依赖于两个主要属性:它的存储类和它的类型。存储类决定了与该标识的对象相关联的存储区域的生命周期,类型决定了该对象的值的含义。一个名字还有一个作用域和一个连接,作用域即程序中可见此