0.2 目标读者和内容结构

本书的目标读者为:

  • 粗略地读过 C 语言的入门书籍,但还是对指针不太理解的人

  • 平时能自如地使用 C 语言,但实际对指针理解还不够深入的人

本书由以下内容构成。

  • 第 1 章:从基础开始——预备知识和复习

  • 第 2 章:做个实验见分晓——C 是怎样使用内存的

  • 第 3 章:揭秘 C 的语法——它到底是怎么回事

  • 第 4 章:数组和指针的常用用法

  • 第 5 章:数据结构——真正的指针的使用方法

  • 第 6 章:其他——拾遗

第 1 章和第 2 章主要面向初学者。从第 3 章开始的内容,是为那些已经具备一定经验的程序员或者已经读完第 1 章的初学者准备的。

面向初学者,第 1 章和第 2 章从“指针就是地址”这个观点开始讲解。

通过 printf()来“亲眼目睹”地址的实际值,应该说,这不失为理解指针的一个非常简单有效的方式。

对于那些“尝试学习了 C 语言,但是对指针还不太理解”的人来说,通过自己的机器实际地输出指针的值,可以相对简单地领会指针的概念。

首先,在第 1 章里,针对 C 语言的发展过程(也就是说,C 是怎样“沦为”让人如此畏惧的编程语言的)、指针以及数组进行说明。

对于指针和数组的相互关系,市面上多数的 C 语言入门书籍只是含混其辞地做了敷衍解释(包括 K&R*,我认为该书是诸恶之源)。这还不算,他们还将本来已经用数组写好的程序,特地用指针运算的方式重新编写,还说什么“这样才像 C 语言的风格”。

* K&R 被称为 C 语言的 宝典(中文版叫《C 程 序设计语 言 (第 2 版·新版)》),在后面 我们会提及这本书的 背景。此书的作者之一 就是 C 语 言之父 Dennis Ritchie 本人。

像 C 语言的风格?也许是可以这么说,但是以此为由炮制出来的难懂的写法,到底好在哪里?哦?执行效率高?为什么?这是真的吗?

产生这些疑问是正常的,并且,这么想是正确的

了解 C 语言的发展过程,就能理解 C 为什么会有“指针运算”等这样奇怪的功能。

第 1 章中接下来的内容也许会让初学者纠结,因为我们将开始接触到数组和指针的那些容易让人混淆的语法。

第 2 章讲解了 C 语言实际上是怎样使用内存的。

在这里同样采用直观的方式将地址输出。请有 C 运行环境的读者一定亲手输入例程的代码,并且尝试运行。

对于普通的局部变量、函数的参数、static 变量、全局变量及字符串常量(使用" "包围的字符串)等,知晓它们在内存中实际的保存方式,就可以洞察到 C 语言的各种行为。

遗憾的是,几乎所有使用 C 语言开发的程序,运行时检查都不是非常严密。一旦出现诸如数组越界操作,就会马上引起“内存区域破坏”之类的错误。虽然很难将这些 bug 完全消灭,但明白了 C 如何使用内存之后,至少可以在某种程度上预防这些 bug 的出现。

第 3 章讲解了与数组和指针相关的 C 语言语法。

虽然我多次提到“究竟指针为什么这么难”,但是对于“指针就是地址”这个观点,在理解上倒是非常简单。出现这种现象,其实缘于 C 语言的数组和指针的语法比较混乱。

乍看上去,C 语言的语法比较严谨,实际上也存在很多例外。

对于那些平时和我们朝夕相处的语法,究竟应套用哪条规则?还有,哪些语法需要特殊对待?关于这些,第 3 章里会做彻底的讲解。

那些自认为是老鸟的读者,可以单独拿出第 3 章来读一读,看看自己以前是如何上当的。

第 4 章是实践篇,举例说明数组和指针的常用用法。如果读者理解了这部分内容,对付大部分程序应该不在话下。

老实说,对于已经将 C 语言使用得像模像样的读者来说,第 4 章中举出的例子并没有什么新意。但是,其实有些人对这些语法只是一知半解,很多时候只不过是依照以前的代码“照猫画虎”罢了。

阅读完第 3 章后去读第 4 章,对于那些已经能够熟练使用的写法,你也会惊呼一声:“原来是这个意思啊!”

第 5 章中,解说指针真正的用法——数据结构的基本知识。

前四章中的例子,都是围绕 C 语言展开的。第 5 章里则会涉及其他语言的指针。

无论使用哪种语言编程,“数据结构”都是最重要的。使用 C 语言来构造数据结构的时候,结构体和指针功不可没。

“不仅仅对于 C 语言的指针,连结构体也不太明白”的读者,务必不要错过第 5 章。

第 6 章中,对到此为止还没有覆盖到的知识进行拾遗,并且为大家展示一些可能会遇到的陷阱以及惯用语法。

和类似的书籍相比,本书更加注重语法的细节。

提起语法,就有“日本的英语教育不偏重语法”,以至于给人“就算不明白也没有什么”的印象。确实是这样,我们早在不懂“サ行”怎样变形之前,就已经会说日语了。

但是,C 语言可不是像日语那样复杂的自然语言,它是一门编程语言。

单纯地通过语法来解释自然语言是非常困难的。比如,日语“いれたてのおちゃ”,利用假名汉字变换程序只能变换成“淹れたてのお茶”(中文意思是‘沏好的茶’),尽管如此,同样通过假名变换程序,“いれたてのあついおちゃ”竟然也可以变换成“入れた手の厚いお茶”(中文意思是‘沏好的热腾腾的茶’)1。编程语言最终还是通过人类制订的语法构成的,它要做到让编译器这样的程序能够解释。

1 中文里也有类似的例子,如:他是先知。→他是先知道那件事的人。——译者注

“反正大家都是这么写,我也这么写,程序就能跑起来。”

这种想法,让人感觉有点悲哀

我希望不仅是初学者,那些已经积累了一定经验的程序员也能阅读本书。通过深入理解 C 的语法,可以让我们真正领会直到今天还像“口头禅”一样使用的那些程序惯用写法。

无论如何,让我们做到“知其然知其所以然”,这样有利心理健康,不是吗?