柏动软件

这是译者2020年8月所译《现代C语言》正文首章,原发在微薄上,当时曾想正式出版,但到目前也没有 找到出版合作方,所以到现在也没有出版成(如有机会,还是想出版的)。 本来正式版译文应该还有一些,但匆忙间没有找到。 对于一部完整的技术书籍来说,只有个别章节是不管用的,但还是选择发在这里,一来是充实网站内容, 再者,也大概能够作为一种我们可以做什么的例证。作为软件公司,当然想要更多的业务机会, 但如何证明自己的技术能力也是一个重要问题,这也算是一个努力吧。

请勿转载


关于本书

C编程语言在70年代(20世纪)早期就已出现(参考Ritchie1993】)。从那时起,使用C语言编写的应用程序就以令人难以置信的数量增长。用C语言编写的程序和系统充满了我们的世界:在个人电脑中、在电话中、在相机、机顶盒、冰箱、汽车、大型计算机、以及卫星等等、等等,几乎所有的现代设备都提供了编程接口。

与使用C语言编写的程序和系统的大量涌现形成鲜明对比的是,人们对C语言以及C语言本身还缺乏良好的认知。甚至一些经验丰富的C程序员对C语言的现代进化也存在某种程度上的忽视。之所以会这样,一个可能的原因或许是:C看上去是一门“容易”学习的语言,一些仅有些许经验的编程人员就能够快速编写或通过拷贝代码片段而得到一个执行其预期动作(或至少看上去是)的程序。从某种程度上说,C没有能够成功地驱动它的使用者去攀登更高阶的知识高峰。

本书旨在改变这种片面的看法,故将它按照“层级”的方式进行组织,以反映人们通常对C语言和程序的熟悉程度。这种结构或许与某些读者的习惯相悖,尤其是本书将一些比较难的主题(如指针)分散到几个“层级”中进行介绍,以使读者不过早陷入到一些不当的信息当中【以免读者过早陷入一些不当的信息之中】。后面会简短介绍本书的组织结构细节。

虽然,还有一些对其他编程语言也普适有效的概念(比如JavaPythonRubyC#C++等),但本书主要着力于C语言的独特概念和实践,尤其是对在使用C编程时非常有用的内容。

C的版本

本书的书名已给出了暗示,现代的C语言与它的原作者当初设计它时的样子已经不大相同了。从出现时开始,C语言就一直处在持续的调整和改进中,并通常将早期的C语言称为K&R C(Kernighan and Ritchie C)。在使得C语言开始流行的第一本书出现之后(Kernighan and Ritchie1978】),对它的标准化和扩展就一直在进行,并分别在1989年、1999年,2011年和2018年发布了一系列C语言的标准,通常称为C89C99C11C17(译注--有时也称为C18)。这一进程现在是由ISO(国际标准化组织)负责。C语言标准委员会为了保证实现新标准的编译器依然向后兼容原来的C标准(即C89),付出了非常多的努力——亦即,使用实现了新标准的编译器依然可以将符合旧标准的C代码编译成具有同样意义的可执行代码。不幸的是,这种向后的兼容性产生了一个不好的副作用——就是它不能驱动人们去更新他们的项目代码以使用C语言的新特性,从而获得这些新特性带来的好处。

本书将主要参考由JTC1/SC22/WG142018】定义的C17,但在写作本书时,有些编译器尚未完全地实现这一标准。如果你要编译书中的示例代码,则至少需要一个实现了大部分C99标准的编译器。对于由C11带来的某些变化(相对于C99),则可以使用P99这样的宏程序包来进行模拟。该程序包可以从 处 取得。

CC++

当前,编程已变成一种重要的文化和经济活动,而C语言在编程世界中仍然占有重要的地位。与所有的人类活动一样,C语言的进化过程也受到许多因素的影响:如组织或个人的兴趣、政策的、美学的、思维方式的、运气的、忽视的(?)、自私性、自负、宗派主义、……(可以在这里加入你的主要动机)。因此C语言的发展不曾也不可能那么理想化,它存在的某些瑕疵和遗留特性只能从它们的历史和社会背景出发才可能得到理解。

C语言的发展过程有着重要影响的是在早期它的姐妹语言C++的出现。人们通常存在一个误解,即认为C++是通过在C语言之上添加某些特殊功能得到的。即使这在历史上是正确的(C++是从极早期的C发展而来),在今天它们之间的关联也不再那么紧密了事实上CC++都是在30多年前分别来自一个共同的祖先,并从那时起就各自沿着自己的发展路径演化了但是这两种语言的演化过程又不是完全隔绝的,这些年来它们一直互相交互并彼此吸收对方的一些概念。比如近期加进去的原子操作和线程等新功能,就是在两个标准委员会的紧密合作下设计出来的。

但尽管如此,它们之间的许多差别仍然是存在的,而且本书所说的全部都是关于C语言的,而非C++,书中的很多示例代码甚至不能通过C++编译器的编译。所以我们不应该混合这两种语言的源代码。

  • 要点ACC++是不同的语言:不要把他们搞混了,更不要把他们的代码混合在一起。

如果你通读本书,就会看到很多像上面这样做了标记的行。他们都是功能特性、规则、建议等,诸如此类的要点总结。在本书的最后有一个这样的要点总结的列表,可以作备忘录使用。

要求:

为了能够从本书有所获益,读者至少需要满足以下这些最低要求;如果您有任何不确定的地方,请首先设法解决掉,否则会在后面浪费大量时间。

首先,你不可能不通过任何练习就掌握一门编程语言,所以你需要一个能够自己控制的编程环境(通常在台式计算机或便携电脑上)。这个编程环境可以是集成的(集成开发环境),也可以是一组独立工具的集合。但提供这样的环境的平台很多,所以很难给出一个确定的建议。在类Unix平台比如LinuxApplemacOS系统下,可以使用emacsvim等编辑器,编译器则有c99gccclang等。其余的你至少需要做到以下诸点:

1)能够浏览你的文件系统:电脑中的文件系统通常是以层级状的目录形式组织,你需要浏览这些目录以查找和操作你的文件。

2)编辑程序源码:这与在文字处理环境中编辑一封信件是不同的。你使用的编辑器需要对C语言有基本的理解,当你使用它打开一个源文件时(通常以.c作为后缀),它会将关键字以高亮形式显示,并根据大括号的嵌套关系缩进代码。

3)执行程序:你在这里看到的程序都是很基础、没有图形界面的,他们需要从命令行中进行启动。编译器就是需要这样启动的程序的一个例子。在类Unix环境下,命令行常被称为壳(shell),并在终端(consoleterminal)中启动。

4)编译程序文本:某些环境中提供了菜单按钮或键盘快捷键来启动编译,另一种方式是在终端或命令行下启动编译器。你使用的编译器必需是实现了较新标准的,否则就要浪费时间了。

如果你之前从未编写过程序,这本书对你而言可能会有些难度。如果你了解下面任何语言则都会有所帮助:比如BasicC(旧版本的)、 C++FortranRbashJavaScriptJavaMatlabPerlpythonScilab等。另外,你可能是有某种编程的经历的,但自己却未注意到,比如有很多技术规范实际上就是某种特殊的语言,如编写网页用的HTML、编辑文档格式用的LaTeX等,使用过它们就可以作为一个很有用的类比。

另外,你应该知道一些下面这些概念(当然,在你所熟悉的语境中它们的确切含义与在C语言中的含义未必那么一致):

1)变量——持有值的命名的实体,

2)条件语句——根据具体条件确定做(或不做)某事,

3)迭代——重复做某事指定次数或直到满足某种条件为止。

源代码:

书中所列代码片段可在网址处下得: 下载后就可以在 上下文环境中审阅并编译、然后亲自运行它们。该压缩文件中还包含了一个Makefile文件,其中列出了编译这些文件所需的组件。但它主要是针对Linux、或更通用一点说、主要是针对POSIX系统的,但它们对于找出在其他系统中所需要的条件也是有帮助的。

练习与挑战:

贯穿本书,提供了很多练习来启发读者思考正在学习的概念。读者最好是在阅读的同时直接独立地完成它们。另外,书中还专门列出了一类称为“挑战”的项目,完成它们则需要更高的要求。你甚至需要做更多一些的研究以弄清它们是关于什么的,解决方案也可能不那么容易直接想到。完成它们需要更多的努力,更多的时间——可能是若干个小时,与读者的熟悉程度有关,甚至需要若干天的工作量。这些挑战中涉及的主题都是作者本人在平常经历中较感兴趣的“有趣问题”的总结,如果读者在自己的学习或工作中遇到与此相关的其他问题或项目,也同样适用。重要的是,读者要训练自己首先到其他地方获取帮助和想法,然后亲自动手解决问题。人们只有跳入水中才能真正地学习游泳。

组织形式:

本书组织成“层级”的形式,并分别标以03的数字。起始层级0冠以“初遇”之名,主要概述使用C语言编程的基本问题。它的主要作用是向读者揭示并让读者熟悉C语言所使用的一些概念、专门词汇和观点1。到了该层级的结尾,即使读者没有使用C编程的经历,也应该可以理解简单的C程序的结构,并可以自己动手编写C程序了。

层级1命名为“去熟悉”,着重于C语言中最基本的概念和功能,比如控制结构、数据类型、操作符,以及函数等,可以让读者更深入地理解所运行的程序。这些知识对于入门级的算法课程以及其他处于同一水平的工作是足够了。但要注意,指针在这里尚未做充分介绍。

层级2称为“去感知”,将深入到C语言的核心内容。这部分会完整介绍指针,带你熟悉C的内存模型,向你介绍大部分的C标准函数库接口。完成本层级的学习,你就应该能够比较专业的编写C程序代码了,也因此,本层级会对C程序的组织形式和编写方法作一些基本的讨论。我个人非常期望所有计算机科学或C编程相关专业的工程院校毕业生都能够掌握这一层级的知识,而非仅满足于较低的层级。

层级3则名之为“去经历”,主要深入一些特殊的主题的细节,比如性能、恢复执行、原子性、线程,以及泛型编程等。当你在现实世界中遇到这些问题时可能会发现,它们是最具探索性的内容了。但不管怎么说,作为一个整体,他们是结束本教程的必要部分,并提供读者关于C语言的完整知识。任何具有多年专业C编程经验或者带领以C语言为主要编程语言的软件项目的人都应该掌握本层级。

关于作者:

作者在波恩大学和柏林技术大学完成了他的数学专业学习,在此期间他的研究覆盖了离散数学和有效计算的交叉问题。从1998年开始,他作为资深科学家在法兰西国家研究院从事计算机科学和控制方面的研究(INRIA),先是在位于南锡的LORIA实验室,并于2013年始在位于斯特拉斯堡的ICube实验室。

在他的全部职业生涯中,绝大多数科学研究工作都是通过开发软件完成的,起初主要是使用C++,后来则基本上只使用C语言了。他现在服务于法国标准委员会,是国际标准委员会JTC1/SC22/WG14的一名专家,并是C语言标准文档ISO/IEC 98992018的合作编辑。他还拥有一个比较成功的博客,主要关注于C语言编程及相关主题。

1 C语言的特殊观点之一是索引值从0开始,而不是像Fortran中那样从1开始。

上海柏动软件研究开发中心沪ICP备2021007358号 2025年