《C专家编程》一1.4 K&R C

1.4 K&R C

到了20世纪70年代中期,C语言已经很接近目前这种我们所知道和喜爱的形式了。更多的改进仍然存在,但大部分都只是一些细节的变化(比如允许函数返回结构值)和一些对基本类型进行扩展以适应新的硬件变化的改进。(比如增加关键字unsigned和long)。1978年,Steve Johnson编写了pcc这个可移植的C编译器。它的源代码对贝尔实验室之外开放,并被广泛移植,形成了整整一代C编译器的基础。C语言的演化之路如图1-2所示。

图1-2 后期的C

一个非比寻常的Bug

C语言从Algol-68中继承了一个特性,就是复合赋值符。它允许对一个重复出现的操作数只写一次而不是两次,给代码生成器一个提示,即操作数寻址也可以类似地紧凑。这方面的一个例子是用b+=3作为b=b+3的缩写。复合赋值符最初的写法是先写赋值符,再写操作符,就像:b=+3。在B语言的词法分析器里有一个技巧,使实现=op这种形式要比实现目前所使用的op=形式更简单一些。但这种形式会引起混淆,它很容易把

b=-3;  /* 从b中减去3 */

b= -3;  /* 把-3赋给b */

搞混淆。

因此,这个特性被修改为目前所使用的这种形式。作为修改的一部分,代码格式器程序indent也作了相应修改,用于确定复合赋值符的过时形式,并交换两者的位置,把它转换为对应的标准形式。这是个非常糟糕的决定,任何格式器都不应该修改程序中除空白之外的任何东西。令人不快的是,这种做法会引入一个Bug,就是几乎任何东西(只要不是变量),如果它出现在赋值符后面,就会与赋值符交换位置。

如果你运气好,这个Bug可能会引起语法错误,如:

epsilon=.0001;

会被交换成:

epsilon.=0001;

这条语句将无法通过编译器,你马上就能发现错误。但一条源语句也可能是这样的:

valve=!open;   /*valve被设置为open的逻辑反*/

会悄无声息地交换成:

valve!=open;  /*valve与open进行不相等比较*/

这条语句同样能够通过编译,但它的作用与源语句明显不同,它并不改变valve的值。

在后面这种情况下,这个Bug会潜伏下来,并不会被马上检测到。在赋值后面加个空格是很自然的事,所以随着复合赋值符的过时形式越来越罕见,人们也逐渐忘记了indent程序曾经被用于“改进”这种过时的形式。这个由indent程序引起的 Bug直到20世纪80年代中期才在各种C编译器中销声匿迹。这是一个应被坚决摒弃的东西!
1978年,C语言经典名著The C Programming Language出版了。这本书受到了广泛的赞誉,其作者Brian Kernighan和Dennis Ritchie也因此名声大噪,所以这个版本的C语言就被称为“K&R C”。出版商最初估计这本书将售出1000册左右。截止到1994年,这本书大约售出了150万册(参见图1-3)。C语言成为最近20年最成功的编程语言之一,可能就是最成功的。但随着C语言的广泛流行,许多人试图从C语言中产生其他变种。

图1-3 像猫王艾尔维斯一样,C语言无处不在

时间: 2024-09-21 13:58:16

《C专家编程》一1.4 K&R C的相关文章

《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语言-编程算法 - 最小的k个数 代码(C)

问题描述 编程算法 - 最小的k个数 代码(C) 请解释一下在c语言中怎样编写在输入的N个数中找到k个最小的数 解决方案 排序吧,再输出前k个数 解决方案二: 遍历,找出MAX,移除MAX,循环K遍 解决方案三: 我觉得你的问题是怎么将输入的数保存下来,你可以先定义一个vector. vector vec;int iNUm = 0;while(cin>>iNum)//需要结束的时候输入ctrl+z;{ vec.push_back(iNum);}//最后对整个vec进行排序,取得最小的值 解决方

《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

K&amp;R《C语言程序设计》代码慢录一

昨天,在一品漫城打第三届4VS4室内篮球赛. 我带的队,打三场,输三场,成功淘汰出局~~~:) 哎,到最后,好像打球氛围不太好,我们老了,只为练练身体,友谊第一. 但,好像有些队,只认输赢一样, 一个哥们居然去威胁裁判... 晚上回来吃得少,半夜饿啦,小孩子又跟我们睡觉, 我就起来找食吃,顺便看会K&R的书,尽管在DOUBAN上我给了它差评, 但一路PYTHON看下来,我觉得和这书对照,应该理解得更深入些. 今早突发想学布置JAVA和HADOOP的事.到时再写BLOG. 先上刚才写的书上的样例代

C专家编程 总结

1 类型转换 当执行算术运算时,操作数的类型如果不同,就会发生转换,数据类型一般朝着浮点精度高.长度更长的方向转换,整数型如果转换为signed不会丢失信息,就转换为signed,否则转换为unsigned. K&R C所采用无房户后保留原著,就是当一个无符号类型与int或更小的整型混合使用时,结果类型是无符号类型.   2 C语言中const并不真正表示常量.   3 switch语句的缺点 1)switch语句最大的缺点是它不会在每个case标签后面的语句执行完毕后自动终止. 2)由于bre

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

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

C专家编程 笔记

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

《JavaScript专家编程》——1.2 对象概述

1.2 对象概述 JavaScript是由Brendan Eich创建的一种面向对象编程(OOP)语言,当时他还在Netscape公司工作,花了几周的开发时间就发布了.虽然JavaScript的名字中有个"Java",但它实际上跟Java语言没什么关系.在InfoWorld的一篇对Eich的采访稿中,他解释了JavaScript命名的由来: InfoWorld:据我所知,JavaScript开始的时候叫Mocha,后来改名叫LiveScript,在 Netscape和Sun合并以后才叫