设为首页 加入收藏

TOP

1.3 标准I/O库和C预处理器
2013-10-07 00:08:24 来源: 作者: 【 】 浏览:60
Tags:1.3 标准 I/O 处理器

1.3  标准I/O库和C预处理器

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

与此类似,C语言原先并没有定义I/O,而是由库函数提供。后来,这实际上成了标准机制。可移植的I/O由Mike Lesk编写,最初出现在1972年左右,可在当时存在的3个平台上通用。实践经验表明,它的性能低于预期值。所以,人们对它又进行了优化和裁剪,后来成为标准I/O函数库。

C预处理器大约也是在这个时候被加入的,倡议者是Alan Snyder。它所实现的3个主要功能是:

• 字符串替换:形式类似“把所有的foo替换为baz”,通常用于为常量提供一个符号名。

• 头文件包含(这是在BCPL中首创的):一般性的声明可以被分离到头文件中,并且可以被许多源文件使用。虽然约定采用“.h”作为头文件的扩展名,但在头文件和包含实现代码的对象库之间在命名上却没有相应的约定,这多少令人不快。<

< xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 软件信条

C并非Algol

70年代后期,Steve Bourne在贝尔实验室编写UNIX第7版的shell(命令解释器)时,决定采用C预处理器使C语言看上去更像Algol-68。早年在英国剑桥大学时,Steve曾编写过一个Algol-68编译器。他发现如果代码中有显式的“结束语句”提示,诸如if ... fi或者case ... esac等,调试起来会更容易。Steve认为仅仅一个“}”是不够的,因此他建立了许多预处理定义:

    #define STRING char *
#define IF if(
#define THEN ){
#define ELSE }else(
#define FI ;}
#define WHILE while(
#define DO ){
#define OD ;}
#define INT int
#define BEGIN {
#define END }

这样,他就可以像下面这样编写代码:

    INT compare(s1, s2)
STRING s1;
STRING s2;
BEGIN
WHILE *s1++ == *s2
DO IF *s2++ == 0
THEN return(0);
FI
OD
return(*--s1 - *s2);
END

再看一下相应的C代码:

   int compare(s1, s2)
char *s1, *s2;
{
while(*s1++ == *s2){
if(*s2++ == 0) return(0);
}
return (*--s1 - *s2);
}

Bourne shell的影响远远超出了贝尔实验室的范围,这也使得这种类似Algol-68的C语言变型名声大噪。但是,有些C程序员对此感到不满。他们抱怨这种记法使别人难以维护代码。时至今日,BSD 4.3 Bourne shell(保存于/bin/sh)依然是这种记法写的。

我有一个特别的理由反对Bourne Shell,在我的书桌上堆满了针对它的Bug报告!我把它们发给Sam,我们都发现了这样的Bug:这个shell不使用malloc,而是使用sbrk自行负责堆存储的管理。在维护这类软件时,每解决两个问题通常又会引入一个新问题。Steve解释说他之所以采用这种特制的内存分配器,是为了提高字符串处理的效率,他从来不曾想到其他人会阅读他的代码。

Bourne创立的这种C语言变型事实上促成了异想天开的国际C语言混乱代码大赛(The International Obfuscated C Code Competition),比赛要求参赛的程序员尽可能地编写神秘而混乱的程序来压倒对手(关于这个比赛,以后还有更详尽的说明)。

宏最好只用于命名常量,并为一些适当的结构提供简捷的记法。宏名应该大写,这样便很容易与函数调用区分开来。千万不要使用C预处理器来修改语言的基础结构,因为这样一来C语言就不再是C语言了。

【责任编辑:杜书 TEL:(010)68476606】


回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.1 C语言的史前阶段 下一篇1.9 阅读ANSI C标准,寻找乐趣和..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: