描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787121361838
编辑推荐
C语言的图书多如牛毛,但绝大多数都很单纯,无外乎语法、技巧或者实例。
C语言的教与学,远不止语法和示例这么简单。语言是应用的工具,只能深入到历史和实际应用的土壤里,从现实中寻找这门计算机语言的定位,学习它的语法,认识它所能解决的现实问题。
所以,这本书面向C语言的初学者,结合*的C语言标准9899:2011,不但介绍了和C语言本身有关的各个方面:词法元素、类型、声明、函数、表达式、语句、预处理、标准库,更是以此为主线,融汇了大量的现实和应用场景,从计算机原理、程序设计、编译原理、操作系统接口、数据结构,等等。
C语言的教与学,远不止语法和示例这么简单。语言是应用的工具,只能深入到历史和实际应用的土壤里,从现实中寻找这门计算机语言的定位,学习它的语法,认识它所能解决的现实问题。
所以,这本书面向C语言的初学者,结合*的C语言标准9899:2011,不但介绍了和C语言本身有关的各个方面:词法元素、类型、声明、函数、表达式、语句、预处理、标准库,更是以此为主线,融汇了大量的现实和应用场景,从计算机原理、程序设计、编译原理、操作系统接口、数据结构,等等。
内容简介
C语言的图书多如牛毛,但绝大多数都很单纯,无外乎语法、技巧或者实例。C语言的教与学,远不止语法和示例这么简单。语言是应用的工具,只能深入到历史和实际应用的土壤里,从现实中寻找这门计算机语言的定位,学习它的语法,认识它所能解决的现实问题。所以,这本书面向C语言的初学者,结合*的C语言标准9899:2011,不但介绍了和C语言本身有关的各个方面:词法元素、类型、声明、函数、表达式、语句、预处理、标准库,更是以此为主线,融汇了大量的现实和应用场景,从计算机原理、程序设计、编译原理、操作系统接口、数据结构,等等。为了帮助读者更好地理解C语言、操作系统接口以及用C语言解决实际问题这三者之间的关系,本书还特意提供了一个关系型数据库的实例和一个WEB服务器编程的实例。本书的目标:a.基础。本书面向初学者,介绍C语言的基础知识,但有深度和高度;b.全面。依据C语言的*标准,尽量涵盖它的所有内容;c.标准化。摒弃某些传统的概念、术语和不正确、不精确的阐述;d.新颖。正本清源,采用与传统图书不同的形式来讲解。比如,先介绍#include <stdio.h>是什么东西,怎么来的,有什么用,而不是象别的书一样,一上来就使用,而且对它的功能语焉不详。不单单是讲述C的语法,更深入到与之相关的各个方面,比如操作系统环境、编译器、数据库和WEB应用,通过各种互相结合的场景,让读者真正认识这门语言,真正掌握这门语言,不致于学了之后还是感到茫然。e.通俗易懂。不是指语言上的通俗化和口语化,而是真正地按照认知的规律和过程,由浅入深,由表及里,不但知其然,还要知其所以然。
目 录
第1章 从1加到100
1.1 如何从1加到100
1.1.1 标准整数类型
1.2 相加过程的实现
1.2.1 左值和左值转换
1.2.2 表达式的值
1.2.3 运算符的优先级
1.2.4 运算符的结合性
1.3 源文件
1.3.1 函数
1.3.2 return语句
1.3.3 main函数
第2章 程序的翻译、执行和调试
2.1 C实现
2.2 程序的翻译和执行
2.3 程序的调试
2.4 集成开发环境
2.5 执行环境
2.6 从1加到N
2.6.1 注释
2.6.2 函数调用和函数调用运算符
2.6.3 函数原型
第3章 更多的相加方法
3.1 变量的初始化
3.2 认识复合赋值
3.3 认识递增运算符
3.4 初识复杂的表达式
3.5 认识关系运算符
3.6 求值 50
3.7 认识逗号表达式
3.7.1 全表达式和序列点
3.8 认识表达式语句
3.9 认识递减和逻辑求反运算符
3.10 参数值的有效性检查
3.10.1 认识if语句
3.10.2 认识逻辑或运算符
3.10.3 未定义的行为
3.10.4 摇摆的else子句
3.10.5 认识逻辑与运算符
3.11 认识标号语句和goto语句
第4章 指针不是指南针
4.1 认识一元&和一元*运算符
4.2 什么是指针
4.3 指针类型的变量
4.4 指向函数的指针
4.4.1 函数指示符—指针转换
4.5 返回指针的函数
4.6 掌握C语言需要建立类型的观念
4.6.1 整型常量
4.6.2 整数—整数转换
4.6.3 表达式的类型
4.6.4 认识整型转换阶和整型提升
4.6.5 指针—整数转换
4.6.6 指针—指针转换
4.7 指向指针(类型)的指针
第5章 准备显示累加结果
5.1 什么是数组
5.1.1 数组变量的声明
5.1.2 数组变量的初始化
5.1.3 认识sizeof和乘性运算符
5.1.4 认识变长数组
5.2 文字和编码
5.2.1 字符数组
5.2.2 字符常量
5.2.3 脱转序列
5.2.4 字面串和字符串
5.3 访问数组元素
5.3.1 数组—指针转换
5.3.2 指针运算和for语句
5.3.3 下标运算符
5.3.4 指针的递增和递减
5.4 指向数组的指针
5.5 元素类型为指针的数组
5.8 将数字转换为字符串
5.9 元素类型为数组的数组
第6章 输入和输出
6.1 输入输出那点事
6.2 系统调用
6.3 编译和链接
6.4 库
6.5 头文件、预处理和翻译单元
6.6 UNIX和类UNIX函数库
6.6.1 限定的类型
6.6.2 变参函数
6.6.3 认识逐位或、逐位与和逐位异或运算符
6.6.4 指向void的指针
6.6.5 结构类型
6.7 Windows动态链接库
6.7.1 认识成员选择运算符“.”
6.7.2 复合字面值
6.7.3 控制台I/O和音频播放
6.7.4 函数main的定义
6.8 C标准库
6.8.1 流
6.8.2 restrict限定的类型
6.8.3 C标准库的实现
6.8.4 标准输入和标准输出
6.8.5 标准I/O的缓冲区
6.8.6 直接的输入输出
6.8.7 格式化输出
6.8.8 格式化输入
6.8.9 格式化输入输出的实例
第7章 字符集和字符编码
7.1 字符集和字符编码的演变
7.1.1 GB2312字符集
7.1.2 GBK和GB18030字符集
7.1.3 UNICODE字符集和编码方案
7.2 多字节字符和宽字符
7.2.1 源字符集和执行字符集
7.2.2 多字节字符、宽字符和字节序
7.3 C语言的国际化
7.3.1 条件包含
第8章 欢迎来到类型之家
8.1 扩展整数类型
8.2 布尔类型_Bool
8.3 枚举类型
8.4 认识switch语句
8.5 联合类型
8.6 复数类型
8.7 限定的类型
8.8 类型的兼容性
8.9 类型转换
8.9.1 实浮点—整数转换
8.9.2 实浮点—实浮点转换
8.9.3 复数—复数转换
8.9.4 实数—复数转换
8.9.5 常规算术转换
第9章 作用域、链接、线程和存储期
9.1 标识符的作用域
9.1.1 函数作用域
9.1.2 文件作用域
9.1.3 块作用域
9.1.4 函数原型作用域
9.1.5 作用域的重叠
9.1.6 名字空间
9.2 标识符的链接
9.3 进程和线程
9.3.1 创建POSIX线程
9.3.2 线程同步
9.3.3 执行时间的测量
9.4 变量的存储期
9.4.1 线程存储期
9.4.2 静态存储期
9.4.3 自动存储期
9.4.4 指派存储期
第10章 Windows编程基础
10.1 如何编写Windows程序
10.1.1 注册窗口类
10.1.2 创建窗口
10.1.3 进入消息循环
10.2 窗口过程
10.2.1 函数调用约定
10.2.2 消息处理
10.2.3 回调函数
10.3 数据链表
10.3.1 作用域的起始点
10.3.2 动态内存分配
10.4 创建和应用所选的字体
10.5 关闭窗口并退出程序
第11章 递归调用、计算器和树
11.1 递归的原理
11.2 复杂计算器
11.2.1 程序的翻译过程
11.2.2 算式的语法
11.2.3 词法分析
11.2.4 函数指定符_Noreturn
11.2.5 语法分析
11.3 树和二叉树
11.4 计算器的二叉树版本
11.4.1 非本地跳转(setjmp/longjmp)
第12章 运算符和表达式
12.1 全表达式
12.2 左值转换
12.3 基本表达式
12.3.1 泛型选择
12.4 后缀表达式
12.4.1 复合字面值
12.4.2 数组下标
12.4.3 函数调用
12.4.4 成员选择
12.4.5 后缀递增
12.4.6 后缀递减
12.5 一元表达式
12.5.1 前缀递增
12.5.2 前缀递减
12.5.3 地址
12.5.4 间接
12.5.5 正号
12.5.6 负号
12.5.7 逐位取反
12.5.8 逻辑非
12.5.9 尺寸
12.5.10 对齐
12.6 转型表达式
12.7 乘性表达式
12.7.1 乘法
12.7.2 除法
12.7.3 取余
12.8 加性表达式
12.8.1 加法
12.8.2 减法
12.9 移位表达式
12.9.1 左移
12.9.2 右移
12.10 关系表达式
12.11 等性表达式
12.12 逐位与表达式
12.13 逐位异或表达式
12.14 逐位或表达式
12.15 逻辑与表达式
12.16 逻辑或表达式
12.17 条件表达式
12.18 赋值表达式
12.18.1 简单赋值
12.18.2 复合赋值
12.19 逗号表达式
1.1 如何从1加到100
1.1.1 标准整数类型
1.2 相加过程的实现
1.2.1 左值和左值转换
1.2.2 表达式的值
1.2.3 运算符的优先级
1.2.4 运算符的结合性
1.3 源文件
1.3.1 函数
1.3.2 return语句
1.3.3 main函数
第2章 程序的翻译、执行和调试
2.1 C实现
2.2 程序的翻译和执行
2.3 程序的调试
2.4 集成开发环境
2.5 执行环境
2.6 从1加到N
2.6.1 注释
2.6.2 函数调用和函数调用运算符
2.6.3 函数原型
第3章 更多的相加方法
3.1 变量的初始化
3.2 认识复合赋值
3.3 认识递增运算符
3.4 初识复杂的表达式
3.5 认识关系运算符
3.6 求值 50
3.7 认识逗号表达式
3.7.1 全表达式和序列点
3.8 认识表达式语句
3.9 认识递减和逻辑求反运算符
3.10 参数值的有效性检查
3.10.1 认识if语句
3.10.2 认识逻辑或运算符
3.10.3 未定义的行为
3.10.4 摇摆的else子句
3.10.5 认识逻辑与运算符
3.11 认识标号语句和goto语句
第4章 指针不是指南针
4.1 认识一元&和一元*运算符
4.2 什么是指针
4.3 指针类型的变量
4.4 指向函数的指针
4.4.1 函数指示符—指针转换
4.5 返回指针的函数
4.6 掌握C语言需要建立类型的观念
4.6.1 整型常量
4.6.2 整数—整数转换
4.6.3 表达式的类型
4.6.4 认识整型转换阶和整型提升
4.6.5 指针—整数转换
4.6.6 指针—指针转换
4.7 指向指针(类型)的指针
第5章 准备显示累加结果
5.1 什么是数组
5.1.1 数组变量的声明
5.1.2 数组变量的初始化
5.1.3 认识sizeof和乘性运算符
5.1.4 认识变长数组
5.2 文字和编码
5.2.1 字符数组
5.2.2 字符常量
5.2.3 脱转序列
5.2.4 字面串和字符串
5.3 访问数组元素
5.3.1 数组—指针转换
5.3.2 指针运算和for语句
5.3.3 下标运算符
5.3.4 指针的递增和递减
5.4 指向数组的指针
5.5 元素类型为指针的数组
5.8 将数字转换为字符串
5.9 元素类型为数组的数组
第6章 输入和输出
6.1 输入输出那点事
6.2 系统调用
6.3 编译和链接
6.4 库
6.5 头文件、预处理和翻译单元
6.6 UNIX和类UNIX函数库
6.6.1 限定的类型
6.6.2 变参函数
6.6.3 认识逐位或、逐位与和逐位异或运算符
6.6.4 指向void的指针
6.6.5 结构类型
6.7 Windows动态链接库
6.7.1 认识成员选择运算符“.”
6.7.2 复合字面值
6.7.3 控制台I/O和音频播放
6.7.4 函数main的定义
6.8 C标准库
6.8.1 流
6.8.2 restrict限定的类型
6.8.3 C标准库的实现
6.8.4 标准输入和标准输出
6.8.5 标准I/O的缓冲区
6.8.6 直接的输入输出
6.8.7 格式化输出
6.8.8 格式化输入
6.8.9 格式化输入输出的实例
第7章 字符集和字符编码
7.1 字符集和字符编码的演变
7.1.1 GB2312字符集
7.1.2 GBK和GB18030字符集
7.1.3 UNICODE字符集和编码方案
7.2 多字节字符和宽字符
7.2.1 源字符集和执行字符集
7.2.2 多字节字符、宽字符和字节序
7.3 C语言的国际化
7.3.1 条件包含
第8章 欢迎来到类型之家
8.1 扩展整数类型
8.2 布尔类型_Bool
8.3 枚举类型
8.4 认识switch语句
8.5 联合类型
8.6 复数类型
8.7 限定的类型
8.8 类型的兼容性
8.9 类型转换
8.9.1 实浮点—整数转换
8.9.2 实浮点—实浮点转换
8.9.3 复数—复数转换
8.9.4 实数—复数转换
8.9.5 常规算术转换
第9章 作用域、链接、线程和存储期
9.1 标识符的作用域
9.1.1 函数作用域
9.1.2 文件作用域
9.1.3 块作用域
9.1.4 函数原型作用域
9.1.5 作用域的重叠
9.1.6 名字空间
9.2 标识符的链接
9.3 进程和线程
9.3.1 创建POSIX线程
9.3.2 线程同步
9.3.3 执行时间的测量
9.4 变量的存储期
9.4.1 线程存储期
9.4.2 静态存储期
9.4.3 自动存储期
9.4.4 指派存储期
第10章 Windows编程基础
10.1 如何编写Windows程序
10.1.1 注册窗口类
10.1.2 创建窗口
10.1.3 进入消息循环
10.2 窗口过程
10.2.1 函数调用约定
10.2.2 消息处理
10.2.3 回调函数
10.3 数据链表
10.3.1 作用域的起始点
10.3.2 动态内存分配
10.4 创建和应用所选的字体
10.5 关闭窗口并退出程序
第11章 递归调用、计算器和树
11.1 递归的原理
11.2 复杂计算器
11.2.1 程序的翻译过程
11.2.2 算式的语法
11.2.3 词法分析
11.2.4 函数指定符_Noreturn
11.2.5 语法分析
11.3 树和二叉树
11.4 计算器的二叉树版本
11.4.1 非本地跳转(setjmp/longjmp)
第12章 运算符和表达式
12.1 全表达式
12.2 左值转换
12.3 基本表达式
12.3.1 泛型选择
12.4 后缀表达式
12.4.1 复合字面值
12.4.2 数组下标
12.4.3 函数调用
12.4.4 成员选择
12.4.5 后缀递增
12.4.6 后缀递减
12.5 一元表达式
12.5.1 前缀递增
12.5.2 前缀递减
12.5.3 地址
12.5.4 间接
12.5.5 正号
12.5.6 负号
12.5.7 逐位取反
12.5.8 逻辑非
12.5.9 尺寸
12.5.10 对齐
12.6 转型表达式
12.7 乘性表达式
12.7.1 乘法
12.7.2 除法
12.7.3 取余
12.8 加性表达式
12.8.1 加法
12.8.2 减法
12.9 移位表达式
12.9.1 左移
12.9.2 右移
12.10 关系表达式
12.11 等性表达式
12.12 逐位与表达式
12.13 逐位异或表达式
12.14 逐位或表达式
12.15 逻辑与表达式
12.16 逻辑或表达式
12.17 条件表达式
12.18 赋值表达式
12.18.1 简单赋值
12.18.2 复合赋值
12.19 逗号表达式
前 言
前 言
毋庸置疑,C是非常流行的编程语言。正是因为流行,和它有关的图书之多,可以用多如牛毛、汗牛充栋来形容。
既然都已经这么多了,那我为什么还要再来一本,给牛增加负担呢?原因很简单:想看看是否能用一种和别人不同的方法来把C语言讲清楚。这本书面向初学者,但是,已经学过C语言的人也不妨读一读,因为我的讲解方法和对很多问题的阐述和别人不一样。请放心,我们不胡来,C语言有自己的标准,我们始终按标准来解释一切。当然,自负是人类的共性,这本书是否真的能把C语言讲清楚,还得靠读者来检验。
C语言难学吗?来自这个行业的声音始终自相矛盾。一方面,很多过来人声称C语言其实很简单;另一方面,很多初学者觉得很难,不得其门而入。仅就语法而言,C语言确实比较简单。但是,这种简单性使得很多人对它的掌握只停留在似是而非的表面上。似是而非的学习一开始很轻松,但你走不远。实际上,即使是声称已经掌握了这门编程语言的人,对很多语法要素的认识和理解也是错误的,在书写稍微复杂一些的代码时,也发现自己突然变得糊涂起来。
那么,学习C语言的诀窍在哪里呢?
首先,掌握它的类型系统并学会以类型的观点来构造和解析程序中的代码,这样你就不会迷路。如果你没有掌握C语言的类型系统,不会从类型的角度来分析一个表达式,说明你并没有掌握C语言。
其次,你要了解C语言在整个计算机系统中的位置,知道它和操作系统或者硬件之间的关系;尤其是要理解库和C语言的关系,要明白是库拓展了C语言的实用性。除了C语言本身的简洁、优美和强大的表达能力外,C标准库和其他形形色色的库也是C语言变得流行并威力无穷的重要因素。
写一本编程语言的通俗入门教材,最痛苦的莫过于你不能一下子展现事物的全貌和众多细节。尽管你知道它,也渴望表达,然而毫不客气地说,读者们并不需要它。读者不了解原委,没有耐心,记不住,而且恐惧。为此,本书力求在以下几个方面做一些突破:
首先,C语言的知识点是网状的,是互相牵扯和交叉的,如果不加以梳理,随着阅读的深入,读者不理解的概念和术语将越来越多,从而产生挫败感。为了克服这一问题,我们把它变成线性的,还没讲到的内容一概不提,没讲过的概念一概不用;讲过了,有印象了,掌握了,再用来解释新的知识。
其次,对于一本C语言的图书或者教材来说,最怕的是陷于细节而无法自拔,这往往会使读者成为语法机器而不能领略C语言的全貌,不知道C语言到底有什么实际的用处,更不知道哪些知识才是最重要的。
因此,在内容的组织上,这本书的宗旨是先观其大略,而不是一上来就究其细节。如果只是陈列各种语法元素及其细节,我们可能需要写几百上千页,各种示例和习题堆砌其中。学生学完了,习题也做完了,还是莫名其妙,不知道C语言到底在整个计算机体系结构中处于什么位置,它和操作系统的关系是什么,也不知道为什么别人的程序可以播放音乐、处理图片、过滤网络数据包,而自己的程序只能打印哪些学生的成绩高于60分。
第三,考虑到类型系统的重要性,从本书一开始就逐渐强化类型的知识和基于类型的语法分析。这是掌握C语言的关键,不可等闲视之。
第四,多数教材和图书都从一个令初学者抓狂的语句
printf (“hello world”);
开始,其理由是初学者可以马上看到“成果”,增加他们的学习兴趣。然而,除非是面向有编程经验的读者,否则这样做可能弊多利少。一方面,printf只是一个普通的输入输出函数,而且并不是C语言的组成部分,但初学者可能会先入为主地认为它就是C语言里的大梁;另一方面,这个函数并不是它表面上看起来的那样简单,实际上涉及多个知识点和概念,而且无法在一本书的开始部分完全展开。对于初学者来说,从一开始就将他们引入一个迷局可能并不值得。
考虑到这些,本书一反常态,将输入输出留到第6章单独讲述。在此之前,我们用调试软件来跟踪程序的执行过程并观察执行结果。事实上,程序调试是非常重要的技能,所以本书这样安排应该是科学的。
第五,本书有一章是专门介绍Windows编程的,虽然如走马观花一样简单,也会令某些读者质疑,毕竟C语言无关具体的硬件和操作系统平台。之所以这样安排,主要的目的是让读者领略C语言是如何在具体的平台上发挥作用的,以及库在这个过程中所起到的作用和扮演的角色,并从一个侧面解答C语言到底有什么用的问题。尽管C语言不依赖于平台,但用C语言写出来的程序却需要在具体的平台上执行。
第六,本书引入了很多概念和术语,但在正文中夹杂这些术语的英文拼写可能会对部分读者造成阅读障碍。考虑到这一点,我们在每一章的前面用思维导图单独列出,这样做的另一个好处是可以让读者清楚地知道本章中都讲了哪些内容。
第七,这本书开篇没有讲C语言的由来、历史、优点和应用领域,通常来说,这是一本C语言教材的格式化组成部分。但考虑到别的书都已经讲了,网络上也到处都有,所以我就没必要再啰唆了,请大家不要见怪。
最后,这不是一本类似于辞典或者语法参考手册之类的书,内容的组织具有渐进和逐步展开的特点,应该从第1章开始顺序阅读。在内容的组织上,本书前半部分以如何实现输入输出为主线:第1章引入C语言编程的基本概念和要素;第2章讲解程序的调试;第3章快速介绍C语言里的大部分表达式和语句类型;第4和第5章介绍指针和数组,为输入输出做最后的铺垫;第6章完整介绍输入输出。在积累了相当的知识和经验后,本书后半部分以如何实现汉字的处理(第7章)、如何编写Windows程序以及编写一个复杂计算器为主线(第8、9、10、11章),继续讲解C语言的语法。为方便起见,第12章详细介绍了C语言里的每一种表达式。
在学习这门编程语言之前,必须先了解计算机的工作原理,有使用计算机的经验。对于大学新生来说,我并不担心这一点,学校自有他们的教学计划和进度安排;对于自学这门编程语言的人来说,这是需要注意的。
纸质书的内容承载力有限,为了帮助大家更好地使用本书和理解书中的内容,我会准备一些辅助的学习资料,比如导读和习题解析之类的文档,它们都存放在我的个人网站上,网站的地址就在下面。当然,如果你有什么意见和建议,也可以在网站上留言,或者通过下面的电子邮件地址与我联系。
在即将出版之前,编辑同学希望我能在前言里提一提我以前写过的书。说白了,就是要做做广告。我当时就大义凛然地一口回绝:“此事决不可为!谦虚谨慎乃做人之根本,休想让朕把写过《穿越计算机的迷雾(第2版)》和《x86汇编语言:从实模式到保护模式》这两本书的事说出来!”
王晓波和李双圆参与了本书的写作,我们在此共同祝愿读者们阅读愉快,早日通过本书掌握C语言的精髓。
毋庸置疑,C是非常流行的编程语言。正是因为流行,和它有关的图书之多,可以用多如牛毛、汗牛充栋来形容。
既然都已经这么多了,那我为什么还要再来一本,给牛增加负担呢?原因很简单:想看看是否能用一种和别人不同的方法来把C语言讲清楚。这本书面向初学者,但是,已经学过C语言的人也不妨读一读,因为我的讲解方法和对很多问题的阐述和别人不一样。请放心,我们不胡来,C语言有自己的标准,我们始终按标准来解释一切。当然,自负是人类的共性,这本书是否真的能把C语言讲清楚,还得靠读者来检验。
C语言难学吗?来自这个行业的声音始终自相矛盾。一方面,很多过来人声称C语言其实很简单;另一方面,很多初学者觉得很难,不得其门而入。仅就语法而言,C语言确实比较简单。但是,这种简单性使得很多人对它的掌握只停留在似是而非的表面上。似是而非的学习一开始很轻松,但你走不远。实际上,即使是声称已经掌握了这门编程语言的人,对很多语法要素的认识和理解也是错误的,在书写稍微复杂一些的代码时,也发现自己突然变得糊涂起来。
那么,学习C语言的诀窍在哪里呢?
首先,掌握它的类型系统并学会以类型的观点来构造和解析程序中的代码,这样你就不会迷路。如果你没有掌握C语言的类型系统,不会从类型的角度来分析一个表达式,说明你并没有掌握C语言。
其次,你要了解C语言在整个计算机系统中的位置,知道它和操作系统或者硬件之间的关系;尤其是要理解库和C语言的关系,要明白是库拓展了C语言的实用性。除了C语言本身的简洁、优美和强大的表达能力外,C标准库和其他形形色色的库也是C语言变得流行并威力无穷的重要因素。
写一本编程语言的通俗入门教材,最痛苦的莫过于你不能一下子展现事物的全貌和众多细节。尽管你知道它,也渴望表达,然而毫不客气地说,读者们并不需要它。读者不了解原委,没有耐心,记不住,而且恐惧。为此,本书力求在以下几个方面做一些突破:
首先,C语言的知识点是网状的,是互相牵扯和交叉的,如果不加以梳理,随着阅读的深入,读者不理解的概念和术语将越来越多,从而产生挫败感。为了克服这一问题,我们把它变成线性的,还没讲到的内容一概不提,没讲过的概念一概不用;讲过了,有印象了,掌握了,再用来解释新的知识。
其次,对于一本C语言的图书或者教材来说,最怕的是陷于细节而无法自拔,这往往会使读者成为语法机器而不能领略C语言的全貌,不知道C语言到底有什么实际的用处,更不知道哪些知识才是最重要的。
因此,在内容的组织上,这本书的宗旨是先观其大略,而不是一上来就究其细节。如果只是陈列各种语法元素及其细节,我们可能需要写几百上千页,各种示例和习题堆砌其中。学生学完了,习题也做完了,还是莫名其妙,不知道C语言到底在整个计算机体系结构中处于什么位置,它和操作系统的关系是什么,也不知道为什么别人的程序可以播放音乐、处理图片、过滤网络数据包,而自己的程序只能打印哪些学生的成绩高于60分。
第三,考虑到类型系统的重要性,从本书一开始就逐渐强化类型的知识和基于类型的语法分析。这是掌握C语言的关键,不可等闲视之。
第四,多数教材和图书都从一个令初学者抓狂的语句
printf (“hello world”);
开始,其理由是初学者可以马上看到“成果”,增加他们的学习兴趣。然而,除非是面向有编程经验的读者,否则这样做可能弊多利少。一方面,printf只是一个普通的输入输出函数,而且并不是C语言的组成部分,但初学者可能会先入为主地认为它就是C语言里的大梁;另一方面,这个函数并不是它表面上看起来的那样简单,实际上涉及多个知识点和概念,而且无法在一本书的开始部分完全展开。对于初学者来说,从一开始就将他们引入一个迷局可能并不值得。
考虑到这些,本书一反常态,将输入输出留到第6章单独讲述。在此之前,我们用调试软件来跟踪程序的执行过程并观察执行结果。事实上,程序调试是非常重要的技能,所以本书这样安排应该是科学的。
第五,本书有一章是专门介绍Windows编程的,虽然如走马观花一样简单,也会令某些读者质疑,毕竟C语言无关具体的硬件和操作系统平台。之所以这样安排,主要的目的是让读者领略C语言是如何在具体的平台上发挥作用的,以及库在这个过程中所起到的作用和扮演的角色,并从一个侧面解答C语言到底有什么用的问题。尽管C语言不依赖于平台,但用C语言写出来的程序却需要在具体的平台上执行。
第六,本书引入了很多概念和术语,但在正文中夹杂这些术语的英文拼写可能会对部分读者造成阅读障碍。考虑到这一点,我们在每一章的前面用思维导图单独列出,这样做的另一个好处是可以让读者清楚地知道本章中都讲了哪些内容。
第七,这本书开篇没有讲C语言的由来、历史、优点和应用领域,通常来说,这是一本C语言教材的格式化组成部分。但考虑到别的书都已经讲了,网络上也到处都有,所以我就没必要再啰唆了,请大家不要见怪。
最后,这不是一本类似于辞典或者语法参考手册之类的书,内容的组织具有渐进和逐步展开的特点,应该从第1章开始顺序阅读。在内容的组织上,本书前半部分以如何实现输入输出为主线:第1章引入C语言编程的基本概念和要素;第2章讲解程序的调试;第3章快速介绍C语言里的大部分表达式和语句类型;第4和第5章介绍指针和数组,为输入输出做最后的铺垫;第6章完整介绍输入输出。在积累了相当的知识和经验后,本书后半部分以如何实现汉字的处理(第7章)、如何编写Windows程序以及编写一个复杂计算器为主线(第8、9、10、11章),继续讲解C语言的语法。为方便起见,第12章详细介绍了C语言里的每一种表达式。
在学习这门编程语言之前,必须先了解计算机的工作原理,有使用计算机的经验。对于大学新生来说,我并不担心这一点,学校自有他们的教学计划和进度安排;对于自学这门编程语言的人来说,这是需要注意的。
纸质书的内容承载力有限,为了帮助大家更好地使用本书和理解书中的内容,我会准备一些辅助的学习资料,比如导读和习题解析之类的文档,它们都存放在我的个人网站上,网站的地址就在下面。当然,如果你有什么意见和建议,也可以在网站上留言,或者通过下面的电子邮件地址与我联系。
在即将出版之前,编辑同学希望我能在前言里提一提我以前写过的书。说白了,就是要做做广告。我当时就大义凛然地一口回绝:“此事决不可为!谦虚谨慎乃做人之根本,休想让朕把写过《穿越计算机的迷雾(第2版)》和《x86汇编语言:从实模式到保护模式》这两本书的事说出来!”
王晓波和李双圆参与了本书的写作,我们在此共同祝愿读者们阅读愉快,早日通过本书掌握C语言的精髓。
评论
还没有评论。