《C专家编程》一1.8 ANSI C标准的结构

1.8 ANSI C标准的结构

如果我们岔开话题,快速浏览一下ANSI C标准的出处和内容,对读者应该是有帮助的。ANSI C标准分成四个主要的部分:

第4节:介绍(共5页)。对术语进行介绍和定义。

第5节:环境(共13页)。描述了围绕和支持C语言的系统,包括在程序启动时发生什么,程序中止时发生什么,以及一些信号和浮点数运算。编译器的最低限制和字符集信息也在这一部分介绍。

第6节:C语言(共78页)。标准的这部分是基于Dennis Ritchie数次出版的经典之作“The C Reference Manual”,包括The C Programming Language的附录A。如果对比标准和附录,就会发现大多数标题都是一样的,顺序也相同。标准中的主题用辞生硬,看上去像表1-1那样(空白的子段落被省略)。

最初的附录只有40页,但在ANSI C标准中,足足多了一倍。

第7节:C运行库(共81页)。本节提供了一个遵循标准的编译器必须提供的库函数列表,它们是标准所规定的辅助和实用函数,用于提供基本的或有用的功能。ANSI C标准第7节所描述的C运行库是基于/user/group 1984 年的标准,去除了一些UNIX特有的部分。“/user/group”是一个于1984年成立的UNIX国际用户小组。1989年,它更名为“UniForum”,它现在是一个非盈利性行业协会,其宗旨是完善UNIX操作系统。

UniForum从行为的角度对UNIX进行了成功的定义,这激励了许多有创造性的想法,包括X/Open的可移植性指导方针(第4版,XPG/4出现于1992年12月)、IEEE的POSIX 1003、System Ⅴ Interface Definition(系统5接口定义)以及ANSI C标准函数库。每个人都与ANSI C工作小组协作,确保他们所有的标准草案相互之间保持一致。感谢上帝!

ANSI C标准同时附有一些很有用的附录:

附录F:一般警告信息。在许多常见的情况下,诊断信息并非标准所强制要求,但如果有这方面的信息,肯定对程序员有帮助作用。

附录G:可移植性话题。有一些关于可移植性的一般性建议,把遍布标准各处的所有这方面的建议集中在一个地方。它包括未确定的、未定义的和由编译器定义的行为等方面的信息。

标准设立后轻易不作变动,即使是修改错误

并不能因为标准是由国际标准组织所撰写的就认定它必然完整、一致乃至正确。IEEE POSIX 1003.1-1998标准(它是一个操作系统标准,定义类似UNIX的行为)就存在一个非常有趣的自相矛盾的地方:

“[一个路径名]...最多由PATH_MAX个字节所组成,包括最后面的‘0’字符” ——摘自第2.3节。

“PATH_MAX是一个路径名中最多能出现的字节个数(并不是字符串的长度;不包括最后面的‘0’字符”——摘自第2.9.5节)。

所以,PATH-MAX个字节既包括最后面的‘0’,又不包括最后面的‘0’!

看来需要加以解释。答案(IEEE Std 1003.1-1988/INT,1992版,解释编号:15,第36页)认为标准出现了不一致,不过两个结果可以认为都是正确的(这令人很感奇怪,因为一般的观点认为它们不可能两个都是正确的)。

之所以出现这个问题,是由于在修改草案时,所有出现这个词的地方并未得到全部更新。标准化过程非常重视形式,显得僵化。如要更新,只有投票小组批准后才允许对问题进行修改。

这样的错误也曾出现在C标准最早期的脚注里,也就是所附的Rationale文档。事实上,Rationale现在已不属于C标准的一部分,当标准的所有权移交到ISO时,它就被删掉了。

K&R C和ANSI C之间的区别

阅读本节内容时,我假定你已经完全明白K&R C,对ANSI C也已知道了90%。ANSI C和K&R C的区别分成四大类,按其重要性分列于下:

1. 第一类区别是指一些新的、非常不同的、并且很重要的东西。惟一属于这类区别的特性是原型——把形参的类型作为函数声明的一部分。原型使得编译器很容易根据函数的定义检查函数的用法。

2.第二类区别是一些新的关键字。ANSIC正式增加了一些关键字:enum代表枚举类型(最初出现于pcc的后期版本),const、volatile、signed、void也有各自相关的语义。另外,原先可能由于疏忽而加入到C中的关键字entry则弃之不用。

3.第三类区别被称作“安静的改变”——原先的有些语言特性仍然合法,但它的意思有了一些轻微的改变。这方面的例子很多,但都不是很重要,几乎可以被忽略。在你偶尔漫步于它们之上时,可能由于不注意而被其中一个绊了个趔趄。例如,现在的预处理规则定义得更加严格,有一条新规则,就是相邻的字符串字面值会被自动连接在一起。

4.最后一类区别就是除上面3类之外的所有区别,包括那些在语言的标准化过程中长期争论的东西,这些区别在现实中几乎不可能碰到,如符号粘贴(token-pasting)和三字母词(trigraph)(三字母词就是用3个字符表示一个单独的字符,如果该字符不存在于某种计算机的字符集中,就可以用这3个字符来表示。比如两字母词(digraph)t表示“tab”,而三字母词??< 则表示“开放的花括号”)。
ANSI C中最重要的新特性就是“原型”,这种特性取自C++。原型是函数声明的扩展,这样不仅函数名和返回类型已知,所有的形参类型也是已知的。这就允许编译器在参数的使用和声明之间检查一致性。把“原型”称作是“带有所有参数的函数名”是不够充分的,它应该被称作“函数签名(function signiture)”,或者像Ada那样称作“函数说明(function specification)”。

原型的形成

原型的目的是当我们对函数作前向声明(forward declaration)时,在形参类型中增加一些信息(而不仅仅是函数名和返回类型)。这样,编译器就能够在编译时对函数调用中的实参和函数声明中的形参之间进行一致性检查。在K&R C中,这种检查被推迟到链接时,或者干脆不作检查。使用原型以后,原先的:

char * strcpy();

现在在头文件中的形式如下:

char * strcpy(char *dst, const char *src);

可以省略参数名称,只保留参数类型:

char * strcpy(char *, const char *);

但最好不要省略形参名。尽管编译器并不理睬形参的名称,但它们经常能向程序员们传递一些有用的信息。类似地,函数的定义也从:

char * strcpy(dst, src)
       char *dst, *src;
{ ... }

变成了:

char * strcpy(char *dst, const char *src)  /* 注意没有分号 */
{ ... }

函数头不再以一个分号结尾,而是在后面紧接一个组成函数体的复合语句。

每次编写新函数时都应该使用原型,并确保它在每次调用时都可见。不要回到K&R C老式的函数声明方法,除非需要使用缺省的类型升级(这个话题在第8章详细讨论)。
把同一种东西用几个不同的术语来称呼,确实有点神秘。就好像药品至少有3种名称一样:化学名、商品名和常用名。

时间: 2024-08-01 14:46:13

《C专家编程》一1.8 ANSI C标准的结构的相关文章

《C专家编程》一1.3 标准I/O库和C预处理器

1.3 标准I/O库和C预处理器 C编译器不曾实现的一些功能必须通过其他途径实现.在C语言中,它们在运行时进行处理,既可以出现在应用程序代码中,也可以出现在运行时函数库(runtime library)中.在许多其他语言中,编译器会植入一些代码,隐式地调用运行时支持工具,这样程序员就无须操心它们了.但在C语言中,绝大多数库函数或辅助程序都需要显式调用.例如,在C语言中(必要时),程序员必须管理动态内存的使用,创建各种大小的数组,测试数组边界,并自己进行范围检测. 与此类似,C语言原先并没有定义I

《C专家编程》一导读

前 言 C专家编程 C代码.C代码运行.运行码运行-请! --Barbara Ling 所有的C程序都做同一件事,观察一个字符,然后啥也不干. --Peter Weinberger 你是否注意到市面上存有大量的C语言编程书籍,它们的书名具有一定的启示性,如:C Traps and Pitfalls(本书中文版<C陷阱与缺陷>已由人民邮电出版社出版), The C Puzzle Book, Obfuscated C and Other Mysteries,而其他的编程语言好像没有这类书.这里有一

《C专家编程》一1.5 今日之ANSI C

1.5 今日之ANSI C 到了20世纪80年代初,C语言被业界广泛使用,但存在许多不同的实现和差别.PC的实现者发现了C语言优于BASIC的诸多长处,这一发现更是掀起了C语言的高潮.Mirosoft为IBM PC制作了一个C编译器,引入了几个新的关键字(far, near等)帮助指针处理Intel 80x86芯片不规则的架构.随着其他更多并非基于pcc的编译器的兴起,C语言受到了重复BASIC老路的威胁,也就是可能变成一种多个变种松散相关的语言. 形势渐渐明了,一个正式的语言标准是必需的.幸运

《C专家编程》一1.9 阅读ANSI C标准,寻找乐趣和裨益

1.9 阅读ANSI C标准,寻找乐趣和裨益 有时候必须非常专注地阅读ANSI C标准才能找到某个问题的答案.一位销售工程师把下面这段代码作为测试例发给Sun的编译器小组. 1 foo(const char **p) { } 2 3 main(int argc, char **argv) 4 { 5 foo(arvg); 6 } 如果编译这段代码,编译器会发出一条警告信息: line 5: warning: argument is incompatible with prototype (第5行

《C专家编程》一1.11 轻松一下——由编译器定义的Pragmas效果

1.11 轻松一下--由编译器定义的Pragmas效果 自由软件基金会(Free Software Foundation)是一个独特的组织,它由MIT顶级黑客Richard Stallman所创立.顺便提一下,我们所说的"黑客",它的原先意思是"天才程序员".后来这个称呼被媒体所贬损,致使它在局外人眼中成了"邪恶的天才"的代名词.和形容词"bad"一样,"黑客"现在也有两个相反的意思,必须通过上下文才能明白

《C专家编程》一1.6 它很棒,但它符合标准吗

1.6 它很棒,但它符合标准吗 不要添乱--立即解散ISO工作小组. --匿名人士 ANSI C标准可以说是非常独特的,我们可以从好几个有趣的方面来说明这一点.它定义了下面一些术语,用于描述某种编译器的特点.如果你对这些术语有一个比较好的了解,就有助于你理解什么东西能被语言接受,什么东西不能被语言接受.前两个术语涉及不可移植的代码(unportable code),接下来的两个术语跟坏代码(bad code)有关,而最后两个术语则跟可移植的代码(portable code)有关. 不可移植的代码

由ANSI C标准咬文嚼字发现滴东东

  由ANSI C标准咬文嚼字发现滴东东   乱弹 奥运磨炼曲正酣,钢铁功夫解眼馋: 步履蹒跚遭埋怨:呆呆傻傻惹人烦: 浑浑噩噩心难安:四目相对眼茫然: 龙游浅水被虾戏:死不悔改表乱弹!                           (表:biao第四声)             侯佩|hopy    2008年05月08日于合肥电心         忙来有事,开始重读<< C专家编程 >>.     在第1章的1.9节[阅读ANSI C标准,寻找乐趣和裨益](第19页)中找

《JavaScript专家编程》——9.4 度量JavaScript代码质量

9.4 度量JavaScript代码质量 为了让计算精度上升到最高,客观质量分析以程序化的方式对代码进行分析.这项任务可以使用编程工具完成,这些工具能够在多种情况下评估代码,根据各项指标得到最终的质量得分.本节介绍了静态代码分析,这种方法非常适合评估JavaScript的质量. 静态代码分析 静态代码分析就是不通过运行代码来分析代码的过程.静态分析看起来非常像一个文本编辑器的拼写检查器.拼写检查器扫描文档的正文来寻找错误和含糊之处,而并不需要了解文本的意义.同时,静态代码分析从功能上分析源代码的

C专家编程 笔记

C语言中的符号重载 C语言非常的简洁, 以至于不愿意用太多的符号, 这样有很多符号在不同的地方有不同的含义 这样会让用户很困惑, 这是c的语言特性, 也是设计上的一些失误 static     在函数内部,表示该变量的值在各个调用间一直保持延续性: 对于函数,表示该函数只在本文件中可见 extern  用于变量,表示该变量在其它地方定义: 用于函数定义, 表示全局可见(属于冗余的) void      用于参数列表中,表示该函数参数为空,如int main(void): 用于返回值,表示该函数返