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

简介:

本节书摘来自异步社区《C专家编程》一书中的第1章,第1.4节,作者 【美】Perter Van Der Linde,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.4 K&R C

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


04ab439d50dbb31b7fbdcc7886761cb6c677e64c

图1-2 后期的C


64f67b547f473ce4642065beead1c3fa335a951c

一个非比寻常的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语言中产生其他变种。


0a2c5986dcf9c03d8022712543f193665cb61f09

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

相关文章
|
6月前
|
数据采集 Web App开发 负载均衡
代理IP:数据抓包中的"隐形斗篷"与"加速器"
本文深入解析代理IP在数据抓包中的五大核心作用。一是突破反爬机制,通过IP轮换、请求头伪装和流量混淆隐藏身份;二是突破地理限制,实现城市级或国家级精准定位;三是提升分布式抓取效率,支持并行采集与负载均衡;四是保障数据安全,提供加密传输与匿名防护;五是应对潜在风险,如速度损耗与法律问题。文章结合实际案例,展示代理IP如何从简单中转进化为智能指挥工具,助力开发者高效获取网络信息。
121 4
|
5月前
|
安全 算法 数据安全/隐私保护
远控安全进阶之战:TeamViewer/ToDesk/向日葵设备安全策略对比
在数字化时代,卓越的远程控制软件需兼顾功能与体验,包括流畅连接、高清画质、低门槛UI设计、毫秒级延迟及多功能性,同时要有独树一帜的远控安全技术,通过前瞻性安全策略阻挡网络风险,为用户打造全方位安全体验,在基础安全防护上不断创新。本文选取了当下热门的TeamViewer、ToDesk、向日葵三款远程控制软件,从软件介绍、远控安全策略等多个维度进行深入对比,以呈现一场精彩的远控软件安全进阶“大比拼”。
413 13
|
4月前
|
监控 Oracle Java
JVM JDK JRE 使用指南及组件封装方法详解
本指南全面介绍了JVM、JDK、JRE的使用方法与Java组件封装技巧。内容涵盖JDK安装配置、JRE使用、JVM参数调优(如堆内存设置和垃圾回收器选择),以及类、包的封装实践。通过示例展示工具类与数据访问组件的封装方法,并讲解JAR包创建与发布流程。此外,还提供了常见问题解决方案,如内存溢出处理和依赖冲突管理。帮助开发者掌握高效、规范的Java开发技能,提升代码复用性和可维护性。附带面试资料供进一步学习。
177 0
|
7月前
|
机器学习/深度学习 数据采集 算法
《深度解析DeepSeek-M8:量子经典融合,重塑计算能效格局》
DeepSeek-M8的“量子神经网络混合架构”融合了量子计算与经典算法的优势,开启了协同推理的新纪元。量子计算凭借叠加和纠缠特性,实现并行处理,大幅加速复杂问题解决;经典算法则确保逻辑控制与数据处理的稳定性。该架构在图像识别、金融风险评估及药物研发等领域展现出广阔前景,显著提升能效。尽管仍面临接口优化等挑战,DeepSeek-M8已成为计算领域的重要里程碑,引领未来科技变革。
210 7
|
9月前
|
数据采集 存储 数据处理
Pandas数据应用:时间序列预测
本文介绍了使用 Pandas 进行时间序列预测的方法,涵盖时间序列的基础概念、特征(如趋势、季节性等),以及数据处理技巧(如创建时间序列、缺失值处理和平滑处理)。同时,文章详细讲解了简单线性回归和 ARIMA 模型的预测方法,并针对常见问题(如数据频率不一致、季节性成分未处理)及报错提供了解决方案。通过这些内容,读者可以掌握时间序列预测的基本步骤和技巧。
224 27
|
9月前
|
人工智能 自然语言处理 搜索推荐
云端问道12期实操教学-构建基于Elasticsearch的企业级AI搜索应用
本文介绍了构建基于Elasticsearch的企业级AI搜索应用,涵盖了从传统关键词匹配到对话式问答的搜索形态演变。阿里云的AI搜索产品依托自研和开源(如Elasticsearch)引擎,提供高性能检索服务,支持千亿级数据毫秒响应。文章重点描述了AI搜索的三个核心关键点:精准结果、语义理解、高性能引擎,并展示了架构升级和典型应用场景,包括智能问答、电商导购、多模态图书及商品搜索等。通过实验部分,详细演示了如何使用阿里云ES搭建AI语义搜索Demo,涵盖模型创建、Pipeline配置、数据写入与检索测试等步骤,同时介绍了相关的计费模式。
244 3
|
10月前
|
JavaScript 前端开发
【JavaScript】——JS基础入门常见操作(大量举例)
JS引入方式,JS基础语法,JS增删查改,JS函数,JS对象
|
11月前
|
Rust IDE Java
一些常见的IDE和工具链的配置指南
一些常见的IDE和工具链的配置指南
242 10
|
11月前
|
监控 Devops jenkins
自动化部署与监控:打造高效的DevOps流程
【10月更文挑战第24天】在追求快速迭代和持续交付的软件开发时代,DevOps成为提升团队效率的关键。本文深入探讨如何构建一个高效的DevOps流程,包括自动化部署、监控和故障排除等关键环节。通过实际案例,我们将学习如何利用工具简化运维任务,确保系统稳定运行,并快速响应生产问题。
336 2
|
12月前
|
移动开发 小程序 前端开发
小程序的前端插件都有哪些?
【10月更文挑战第16天】小程序的前端插件都有哪些?
219 1