C语言标准参考手册.docx

上传人:b****5 文档编号:6686887 上传时间:2023-01-09 格式:DOCX 页数:60 大小:62.28KB
下载 相关 举报
C语言标准参考手册.docx_第1页
第1页 / 共60页
C语言标准参考手册.docx_第2页
第2页 / 共60页
C语言标准参考手册.docx_第3页
第3页 / 共60页
C语言标准参考手册.docx_第4页
第4页 / 共60页
C语言标准参考手册.docx_第5页
第5页 / 共60页
点击查看更多>>
下载资源
资源描述

C语言标准参考手册.docx

《C语言标准参考手册.docx》由会员分享,可在线阅读,更多相关《C语言标准参考手册.docx(60页珍藏版)》请在冰豆网上搜索。

C语言标准参考手册.docx

C语言标准参考手册

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.2C89

C99已经替代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关键字

以下标识符被保留为关键字,它们不能用做别的用途:

auto

double

int

struct

break

else

long

switch

case

enum

register

typedef

char

extern

return

union

const

float

short

unsigned

continue

for

signed

void

default

goto

sizeof

volatile

do

if

static

while

有些实现还把单词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'。

单字符常量的值是执行时机器的字符集中的此字符的数值,多字符常量的值由实现定义。

字符常量不包括字符'和换行符,为了表示它们和某些其他的字符,可以使用以下的转义序列(换码序列):

newline

NL(LF)

\n

换行符

horizontaltab

HT

\t

横向制表符

verticaltab

VT

\v

纵向制表符

backspace

BS

\b

回退符

carriagereturn

CR

\r

回车符

formfeed

FF

\f

换页符

audiblealert

BEL

\a

响铃符

backslash

\

\\

反斜线

questionmark

?

\?

问号

singlequote

'

\'

单引号

doublequote

"

\"

双引号

octalnumber

ooo

\ooo

八进制数

hexnumber

hh

\xhh

十六进制数

转义序列\ooo由反斜杠后跟1、2或3个用来确定对应字符的值的八进制数字组成。

一个普通的例子是\0(其后没有数字),它表示字符NUL。

转义序列\xhh由反斜杠开始,后跟x,其后是十六进制数字,用来确定对应字符的值。

数字的个数没有限制,但如果对应的字符的值超过最大的字符的值,那么该行为是未定义的。

对于八进制或十六进制转义字符,如果实现中将类型char看做是有符号的,那么将对字符值进行符号扩展,就好像它被强制转换为char类型一样。

如果\后面的字符不是以上所说明的,那么其行为是未定义的。

在C语言的某些实现中,有一个扩展的字符集,扩展的部分不能用char类型表示。

在该扩展集中,常量是由一个前导L开始(如;L'x'),叫做宽字符常量。

这种常量的类型为wchar_t。

这是一个整数类型,定义在标准头文件中。

与通常的字符常量一样.可以使用八进制和十六进制的转义序列;但是,如果值超过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标识符的含义

标识符也叫名字,可以指代很多实体:

函数、结构标记、联合和枚举,结构或联合的成员,枚举常量,类型定义名字以及对象。

一个对象,有时也称为变量,是一个存储区域。

它的解释依赖于两个主要属性:

它的存储类和它的类型。

存储类决定了与该标识的对象相关联的存储区域的生命周期,类型决定了该对象的值的含义。

一个名字还有一个作用域和一个连接,作用域即程序中可见此名字的区域,连接决定另一区域中的同一个名字是否指代的是同一个对象或函数。

作用域相连接将在11节今讨论。

 

4.1存储类

存储类共有两类:

自动存储类和静态存储类。

一个对象说明的几个关键宇与上下文一起确定了对象的存储类。

自动对象对于一个分程序(见9.3节)来说是局部的,在退出分程序时该对象将消失。

如果没有提到存储类说明.或者如果使用了auto区分符,那么分程序中的说明生成的都是自动对象。

说明为register的对象也是自动的,并且(在可能时)存储在机器的快速寄存器中。

静态对象可以局部于某个分程序,或者对所有分程序来说是外部的。

不论是哪一种情况,在退出和再进入函数和分程序时其值不变。

在一个分程序包括提供函数代码的分程序内,静态对象用关键字static说明。

在所有分程序外部说明的且与函数定义在同一级的对象总是静态的,可以通过使用static关键字使它们局部于一个特定的翻译单元,这使得它们有内部连接。

通过略去显式的存储类或通过使用关键字extern,可以使这些对象全局于整个程序,并有外部连接。

 

4.2基本类型

有几种基本类型。

在C标准库中描述的标准头文件定义了在局部实现中每种类型的最大值和最小值。

C标准库给出的数表示最小的可接受限度。

说明为字符(char)的对象要大到足以存储执行字符集(executioncharacterset)中的任何字符。

如果字符集中的某个字符存储在一个char象中,那么该对象的值等于字符的整数码,并且是非负的。

其他量也可存储在char变量中;但其取值范围,特别是其值是否有符号.依赖于具体的实现。

以unsignedchar说明的无符号字符与普通字符占用同样的空间,但其值总是非负的。

以signedchar显式说明的有符号字符也与普通字符占用同样大的空间。

∙在本书的第1版中没有unsignedchar类型,但它的用途很广泛。

signedchar是新增加的。

除了char类型外,还有3种不问大小的整数类型:

shortint、int和longint。

普通int对象的大小与主机的自然结构一样大,其他大小的整数类型都有特殊的用途。

较长的整数至少要占有与较短整数一样的存储空间;但是具体的实现可以便一般整数(int)有与短整数(shortint)或长整数(longint)有同样的大小;除非特别说明,整数类型都表示有符号数。

以关键字unsigned说明的无符号整数遵守算术模2n的规则,其中n是相应整数表示的位数。

这样对无符号数的算术运算永远不会溢出。

可以存储在带符号对象中的非负值的集合是可以存储在相应的无符号对象中的值的子集,并且这两个集合的重叠部分的表示是一样的。

单精度浮点数float)、双精度浮点数(double)和多精度浮点数(longdouble)中任何类型可能是同义的,但精度由前到后是上升的。

∙longdouble是新增加的类型,在第1版中longfloat与double类型等价,但现在已不再相同。

枚举是具有整型值的一个独特的类型。

与每个枚举相关联的是一个有名常量的集合(见8,4节)。

枚举类型类似于整数类型。

但是,如果某个特定枚举类型的对象被赋于的值不是其常量中的一个,或者被赋于的不是一个同类型的表达式,那么枚举类型通常用于编译器以产生警告信息。

因为以上这些类型的对象可以被解释为数字,所以统称它们为算术类型。

char类型、int族类型,不论大小如何,是否有符号.都统称为整数类型。

类型float、double和longdouble统称为浮点类型。

void类型说明值的一个空集合,它被用来说明那些不产生任何值的函数的类型。

 

4.3派生类型

除了基本类型外,我们还可以通过以下几种方法构造派生类型,这些派生类型从概念上说有无限多个:

    给定类型的对象的数组;

    近日给定类型的对象的函数;

    指向给定类型的对象的指针;

    包含一系列不同类型的对象的结构;

    包含不同类型的几个对象中任意一个的联合。

―般地,在构造对象时可以递归地使用这些方法。

 

4.4类型限定符

对象的类型可以有附加的限定符。

说明为const的对象表明此对象的值不可以改变。

说明为volatile的对象表明它有与优化相关的特殊属性。

限定符既不影响对象的值的范围也不影响其算术属性。

限定符将在8.2节讨论。

 

 

5对象和左值

对象是一个指名的存储区域,左值是指向某个对象的表达式。

左值表达式的一个明显的例子是一个有合适类型与存储类的标识符。

某些运算符可以产生左值。

例如,如果E是一个指针类型的表达式,那么*E是一个左值表达式,它指代由E指向的对象。

名字“左值”来源于赋值表达式E1=E2,其中左运算分量E1必须是一个左值表达式。

对每个运算符的讨论说明了此运算符是否需要一个左值运算分量以及它是否产生一个左值。

 

 

6转换

依据运算分量的不同,某些运算符会引起运算分量的值由某个类型转换为另一个类型。

本节解释这种转换所产生的结果。

6.5节将讨论大多数普通运算符所需的转换;对每个运算符的讨论会在需要时做补充。

 

6.1整提升

在一个表达式中,凡是可以使用整数的地方都可以使用有符号或无符号的字符、短整数和整数的位宇段及枚举类型的对象。

如果原来类型的所有值都可用int类型表示,那么原来类型的值就被转换为int类型;否则就被转换为unsignedint类型。

这一过程称为整提升。

 

6.2整数转换

任何整数转换为某个给定的无符号类型的方法是:

找出与此整数同余的最小的非负值,其模数为该无符号类型能够表示的最大值加l。

在二进制补码表示中,如果该无符号类型的位模式较窄,那么这就相当于左截取:

如果该无符号类型的位模式较宽,那么这就相当于对有符号值进行符号扩展和对无符号值填0。

当任何整数被转换成有符号类型时,如果它可以在新类型中表示出来则其值不变,否则它的值由具体实现定义。

 

6.3整数和浮点数

当把浮点类型的值转换为整数类型时,其小数点部分将被丢弃掉。

如果结果值不能用此整类型来表示,那么其行为是未定义的。

特别地,将负的浮点数转换为无符号整类型的结果没有指定。

当把整类型的值转换为浮点类型时,如果该值在该浮点类型可表示的范围内但不能精确表示,那么结果可以是下一个较高的或下一个较低的可表示值。

如果该值超过可表示的范围,那么其行为是未定义的。

 

6.4浮点类型

当一个精度较低的浮点值被转换为有相同或更高精度的浮点类型时,它的值不变。

当把一个有较高精度的浮点类型的值转换为精度较低的浮点类型时,如果它的值在可表示范围内,那么结果可以是下一个较高的或下一个较低的表示值。

如果结果在范围之外,那么其行为是未定义的。

 

6.5算术转换

许多运算符都会以相似的方式在运算过程中引起转换并产生结果类型。

其效果是将所有运算分量转换为同一类型,并以此作为结果的类型。

这种方式的转换称为普通算术转换。

1.首先,如果一个运算分量为longdouble类型,那么另一个也被转换为longdouble类型。

2.否则,如果一个运算分量为double类型,那么另一个也被转换为double类型。

3.否则,如果一个运算分量为float类型,那么另一个也被转换为float类型。

4.否则,同时对两个运算分量进行整提升,然后,如果一个运算分量为unsignedlongint类型,那么另一个也被转换为unsignedlongint类型。

5.否则,如果一个运算分量为longint类型且另一个运算分量为unsignedint类型,那么结果依赖于longint类型是否可以表示所有的unsignedint类型的值。

如果可以,那么unsignedint类型的运算分量转换为longint;如果不可以,那么两个运算分量均转换为unsignedlongint类型。

6.否则,如果一个运算分量为longint类型,那么另一个也被转换为longint类型。

7.否则,如果―个运算分量为unsignedint类型,那么另一个也被转换为unsignedint类型。

8.否则,两个运算分量均为int类型。

∙这里有两个变化。

第一,对float运算分量的算术运算可以只用单精度而不是双精度;而在第1版中指定所有的浮点运算都是双精度。

第二,当较短的无符号类型与较长的有符号类型一起运算时,不将无符号类型的属性传递给结果类型;而在第1版中无符号类型总是处于支配地位。

新规则稍微有点复杂,但减少了当无符号数与有符号数混合使用时的麻烦。

但当一个无符号表达式与一个同样大小的有符号表达式相比较时仍会得到不期望的结果。

 

6.6指针和整数

指针值可以加上或减去一个整数类型的表达式,在这种情况下,整数表达式的转换按照对加法类运算符的讨论进行(见7.7节)。

两个指向同一数组中同一类型的对象的指针可以进行减法运算.其结果被转换为整数;转换方式按对减法类运算符的讨论进行(见7.7节)。

值为0的整常量表达式或强制转换为类型void*的表达式可通过强制转换、赋值或比较转换为另一种类型的指针。

其结果将产生一个空指针,此空指针等于同一类型的另一空指针,但不等于任何指向函数或对象的指针。

某些其他涉及指针的转换也可进行,但其结果依赖于具体的实现。

这些转换必须由一个显式的类型转换运算符或强制类型转换(见7.5节和8.8节)来指定。

指针可以转换为整数类型,只要此类型足够大;所要求的大小依赖于具体的实现。

映射函数也依赖于实现。

一个整类型对象可以显式地转换为指针类型。

映射总是使一个足够宽的从指针转换来的整数转换回到同一个指针,否则其结果依赖于实现。

指向某一类型的指针可以被转换为指向另一类型的指针,但是如果该指针不指向在存储区域中适当对齐的对象,那么结果指针可能会导致地址异常。

指向某对象的指针在转换成一个指向其类型有更少或相同的存储对齐方式的限制的对象时,可以保证原封不动地再转换回来时。

“对齐”的概念依赖于实现,但char类型的对象有最少的对齐限制。

如将在6.8节中讨论的,指针也可以转换为void*类型,并可原封不动地转换回来。

一个指针可以转换为同样类型的另―个指针.除了增加或删除该指针所指的对象类型的限定符(见4.4节和8.2节)。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1