C 标准库 介绍
介绍
本书将告诉你如何使用符合C 语言的ANSI/ISO标准的库函数。因为已经有很多书出色地讲解了C语言本身,所以本书只专注于"库"这个话题。本书还会告诉你C标准库是如何实现的。本书提供了大约9 000行测试过的可实际工作的代码。我相信,看了C标准库的实现细节后你能更好地理解如何使用它。
库函数的实现代码尽可能地使用标准C,这样做有3个设计目的:首先,它使代码具有可读性和示范性;其次,它使代码在各种计算机体系结构间具有高度可移植性;最后,它能使编写的代码兼顾正确性、性能和规模各方面。
教你如何编写C 程序并不是本书的目的。本书假定你能读懂简单的C程序,对于那些稍有难度的代码,我会向你解释其中的难点和技巧。
C 标准库
是非常强大的,它在多种不同的环境下提供了相当多的功能:它允许用户和实现者使用明确定义的名字空间;它对其所提供的数学函数的健壮性和精确性有非常严格的要求;它率先对适应不同文化习惯的代码提供支持,包括那些拥有很大字符集的文化习惯。
为了能有效利用标准库所提供的强大功能,用户应该了解其实现上的很多隐晦细节。库的实现者必须向用户提供这些细节,以使他们更好地使用标准库。C标准中并没有把这些隐晦的实现细节都很好地描述清楚,因为制定标准的主要目的并不是给库的实现者提供指导。与ANSIC标准一起发布的Rationale也没有对这些细节作出很好的解释。Rationale要服务的对象范围很广,而关注这些细节的标准实现者只是众多服务对象的一部分。
在C的传统实现中并不能找到上面提到的新特性。现在的实现已经可以支持国际化开发中的区域设置(locale)概念。每个区域设置都对应于专属的某个国家、某种语言或者某个职业的特定习惯,一个C程序可以通过修改和查询区域设置来动态地适应多种文化。现在的实现也能支持很大的字符集,如字符数量众多的汉字。C程序能把它们作为多字节字符(multibytecharacter)或者宽字节字符(widecharacter)处理。它也能在这两种形式之间转换。在迅速加剧的市场竞争中,这就使得程序的编写更加简单和标准。
因为以前对这些新特性几乎不存在相应的编程艺术,所以即使是最有经验的C程序员,在使用区域设置、多字节字符和宽字节字符的时候也需要一些指导。所以,这些主题在这里给予了特殊的关注。
细节
本书向用户和实现者解释了库的设计用意和可能用法。通过提供C标准库中所有库函数的实际实现,本书用例子告诉你怎样处理它的细节。在那些没有明确是最好实现方法的地方,它还讨论了可供选择和折中的办法。
一个涉及细节的例子是函数getchar 。头文件<stdio.h> 原则上可以用下面的宏来屏蔽函数的声明:
#define getchar() fgetc(stdin) /* NOT WISE! */
然而,它却不应该这样做,一个合理(即使没有用)的C 程序是
#include <stdio.h>#undef fgetcint main(void) int fgetc=getchar(); /* PRODUCES A MYSTERIOUS ERROR */ return (0);
当然,这个例子有点极端,但它却阐述了即使是一个很好的程序员也可能犯的错误。用户有权要求尽可能少地出现这类奇怪的错误,所以设计者就有义务避免出现这些奇怪的错误。
我最终确定的getchar 宏的形式是
#define getchar () (_Files[0]->_Next < _Files[0]->_Rend\? *_Files[0]->_Next++ : (getchar) ())
它和上面第一次给出的那个显而易见(而且更具可读性)的形式大不相同。第12 章会解释其中的原因。
库的设计
本书还有一个目的,那就是从一般角度教授程序员怎样设计和实现库。从本质上讲,程序设计语言提供的库是一个混合的"袋子"。库的实现者要具备非常广泛的技巧才能处理这个"袋子"中各种各样的内容。仅仅是一个有能力的数值分析员,或者能熟练高效地操作字符串,或者懂得很多操作系统接口方面的知识,都是不够的。编写库不仅需要具备以上所有能力,还需要掌握更多的知识。
已经有很多好书告诉你怎样编写数学函数,也有很多书专门介绍某种特定用途的库。这些都是告诉你怎样使用现有的库。有些书甚至证明某个库的各种设计方案抉择的正确性。很少有书致力于告诉读者全面地构建一个库要求具备的技能。
可复用性
很多书都介绍了设计和实现软件的一般性原则。这些书中提到的方法有结构化分析、结构化设计、面向对象设计和结构化编程等。这些书中的大部分例子只考虑了为某个应用编写的程序。然而,这些原则和方法也同样适用于可复用的库的实现。
但可复用性的目标进一步提高了要求。从结构化设计的角度来看,如果一个库函数没有很高的内聚性,它就不太可能有新的用途。同样,如果它不具备低耦合性,它就会更难使用。简单地说,库函数一定要隐藏它的实现细节并且提供完整的功能。否则,从面向对象的角度看,它们不能实现可复用的数据抽象。
所以本书的最终目的是讨论构建库所特有的设计和实现问题。C标准库的设计是固定的。然而,它从很多方面来看都是一个好的设计,值得讨论。C标准库的实现也可以有很多选择。任何一个选择都要遵守一定的原则,例如正确性和可维护性等。其他的一些选择还要遵循某个项目特定的优先级,例如高性能、可移植性或者小规模等。这些选择和原则也值得讨论。
本书的结构
本书的结构
基本对应C标准库本身。标准库中15个头文件声明或定义了库中所有的名字。本书中每一章讲述一个头文件。大部分头文件都有比较紧凑的内容,书中对此也作了紧凑的讨论。然而,也有一两个很笼统,它们相应的章节自然也会涉及更多的内容。
在本书的每一章中,我都摘录了ISO C 标准的相关部分。(除了格式细节,ISO 和ANSI的C标准是完全相同的。)这些摘录补充说明了库的每一部分通常是怎样使用的。它们也使本书成为一个更完整的参考手册(当然本书比单独阅读C标准要容易理解)。本书也给出了实现那些部分和测试这些实现所需的代码。
每一章最后都附有参考文献和配套习题。假如本书作为大学的教材使用,这些习题可以当成作业。很多习题都只是简单的代码改写,它们可以把某个知识点讲得更清楚或者能够说明在实现上可以做一些合理的修改。那些更具有挑战性的题目都做了标记,可以将它们作为那些长期项目的基础,而自学者则可以把这些习题当作深入思考的入口点。
代码
本书中出现的代码已经在Borland 、GNU 项目和VAX ULTRIX 的C编译器上进行了测试。它通过了广泛使用的PlumHall Validation Suite 的库函数的测试,也通过了那些专门为C实现设计的、发现C实现的缺陷的公共域程序。虽然我尽最大努力使错误减到最少,但仍然不能保证代码完全正确。
同时也请注意本书的代码是受版权保护的。它没有放置在公共域中,也不是共享软件。和那些自由软件基金会(GNU项目)发布的代码不同,它不受"copycenter"协议的保护。我保留本书所有的权利。
合理使用
你可以把书中的代码转变为电子版的形式,供个人使用。你也可以从堪萨斯州劳伦斯市的C用户组那里购买机器可识别的代码。无论哪种情况,你对代码的使用都要遵守版权法关于"合理使用"的规定。合理使用不允许你以任何形式发布这些代码的副本,不论是打印件还是电子版,也不论是免费的还是收费的。
除了以上谈到的,我允许合理使用范围之外的一种重要用途。你可以编译库中的部分并且把生成的二进制目标模块和你自己的代码连接生成可执行文件。无限发布这样的可执行文件是允许的。对这样的副本我不要求任何权利。但是,我强烈要求你声明库(在你的文件中)的存在,不论你用了多少,也不论是修改过的还是没有修改的。请在可执行文件的某个地方把下面的文字包含进去:"本作品的部分代码源自TheStandardC Library,copycenter (c) 1992 by P. J.Plauger,Prentice-Hall出版社出版,这些代码已获授权使用。"随可执行文件一同发布的文档中也要在适当的地方显著地标注这些内容。如果你遗漏了其中的任何内容,将被视为侵权。
许可
你也可以被授权做更多的事。你可以以二进制目标模块的形式发布整个库,甚至可以发布本书中的源文件的副本,不论是否修改过。简单地说,你可以把整个库合并到一个让人们使用它来编写可执行程序的产品中。但是,所有的这些都需要许可证。你可以购买许可证。如果你想购买许可证而且想不断地获得库的支持,请和夏威夷州卡姆艾拉市的PlumHall公司联系。
虽然上面的几段有很浓的商业色彩,但我的主要目的不是推销一个商业产品。我非常信任C标准,也已经很努力地参与了它的制定。我花了很大的精力制定C标准库规范。我想证明我们创建了一个良好的语言标准。编写这个实现和这本书就是为了说明这个简单但很重要的事实。
致谢
马萨诸塞州韦克菲尔德市的Compass公司在本书还没完成的时候就很信任我。他们是我的库代码的第一批使用者,他们帮助我测试、调试,并且在Intel860编译器上使用的过程中对这些库代码进行了改进。特别是IanWells,愿意忍受我的延迟和修改,体现了他良好的专业精神。DonAnderson先生为了使这个库的结构更合理,牺牲了很多休息时间给我发电子邮件。我衷心地感谢Compass公司的每个同事的真诚和耐心。
Prentice-Hall 的出版人PaulBecker对本书也很有信心。他的温和与不懈的激励是本书完成的一个保证。他请了一些匿名的审稿人帮助我,使我的观点更加明确,同时也减少了那些绝对化的语句。Paul的职业精神使我明白了Prentice-Hall能在技术出版领域辉煌这么多年的原因。
写作过程中我搬到了澳大利亚,这个项目面临着重重困难。我的好朋友,澳大利亚White smiths 公司的商业伙伴JohnO"Brien 经常帮助我。他是一个"把荆棘变成玫瑰"的好手。他对 我的帮助很大,不是友谊这个词能概括的。
感谢Prentice Hall 的发行经理AndrewBinnie为我提供了完成这本书所用的激光打印机,他乐于在很多方面帮助我。感谢新南威尔士大学计算机科学系给我提供时间和场所,尽管他们也需要这些来完成他们自己的计划。
Tom Plum 一直告诫我们要深刻理解C 的基础。我也多次从和他对本书中涉及的话题进行的讨论中受益匪浅。DaveProsser也与我分享了他对C 的工作方式的深刻见解。作为ANSI 和ISO C标准的编辑,Dave提供了本书中大量电子版的文本资料。日本东京的高级数据控制公司(率先对C提供日文中的汉字的支持)的两个主要负责人HiroshiFukutomi 和Takashi Kawahara在我了解日本程序员的技术需求的工作中,给了我很多帮助。
这里的大部分材料原来都在The C Users Journal 上发表过。RobertWard是一个很容易相处的出版人,我很感谢他能让我重新使用这些材料。也同样感谢Jim Brodie允许我使用我们合著的Standard C一书中的内容。
阅读技术类书稿是一项很枯燥的任务。John O"Brien 和TomPlum审阅了本书的部分内容并且反馈了很有价值的信息。发现第一次印刷版本中(只是一小部分)错误的人有:Nelson H. F.Beebe、Peter Chubb 、Stephen D. Clamage 、Steven Prton 、Tom Plum 和IanLanceTaylor 。
最后,我要感谢我的家人对我的支持。我的儿子Geoffrey在本书的排版和页面设计方面做了很多工作。我的妻子Tana在这么长的时间里给我提供了巨大的精神支持和后勤保障。他们的参与使我的写作过程充满乐趣。
P. J. Plauger
邦迪,新南威尔士
Word教程网 | Excel教程网 | Dreamweaver教程网 | Fireworks教程网 | PPT教程网 | FLASH教程网 | PS教程网 |
HTML教程网 | DIV CSS教程网 | FLASH AS教程网 | ACCESS教程网 | SQL SERVER教程网 | C语言教程网 | JAVASCRIPT教程网 |
ASP教程网 | ASP.NET教程网 | CorelDraw教程网 |