第一章 C语言的历史 1
1.1 C语言的诞生 1
1.2 早期的C语言 3
1.3 标准I/O库和预处理程序 4
1.4 K&R C 6
1.5 现在的C:ANSI C 8
1.6 标准规定了些什么 10
1.7 对应用编译工具的限制 11
1.8 ANSI C语言标准的结构 12
1.9 了解标准的好处 15
1.10 小的变动 17
1.11 轻松一刻——“开发工具定义的”特性对语言的影响 20
第二章 C语言自身引出的问题 22
2.1 什么是语言引出的问题 22
2.2 第一类错误 23
2.2.1 开关语句 23
2.2.2 邻近文字串的连接 28
2.2.3 函数的缺省可见性 29
2.3 第二类错误 30
2.3.1 符号重载 30
2.3.2 运算符的优先级 31
2.3.3 标准库函数 34
2.4 第三类错误 36
2.4.1 命令行参数的处理 36
2.4.2 空格的作用 37
2.4.3 返回指针的函数 39
2.4.4 lint程序 42
2.5 轻松一刻——真正的语言错误 43
第三章 变量的说明与定义 45
3.1 语言的说明格式 46
3.2 说明的构成 47
3.2.1 结构 49
3.2.2 联合 51
3.2.3 枚举 52
3.3 优先级规则 52
3.3.1 用语法图来理解说明 53
3.4 关于typedef 55
3.4.1 概述 55
3.4.2 类型定义与宏定义 57
3.4.3 名字空间 57
3.5 能解释C语言说明的程序 59
3.6 轻松一刻——软件的实际应用 65
第四章 数组与指针 67
4.1 数组与指针并不相同 67
4.2 我的程序哪儿错了? 67
4.3 说明与定义 68
4.4 数组和指针的存取方式 68
4.5 使定义与说明匹配 71
4.6 数组与指针的其它区别 71
第五章 链接 73
5.1 概述 73
5.2 动态链接的优势 76
5.3 关于链接和库的五个问题 79
5.4 冲突 82
5.5 产生链接记录文件 86
5.6 轻松一刻——猜猜谁在说话:关于图灵测试 87
5.6.1 Eliza 87
5.6.2 Eliza与副总裁 88
5.6.3 医生看医生 89
5.6.4 波士顿奖金 90
5.6.5 结论 90
5.6.6 附言 91
第六章 动态数据结构 92
6.1 a.out和a.out的来历 93
6.2 段 94
6.3 操作系统对a.out文件做些什么 97
6.4 C运行时系统对a.out文件做些什么 99
6.4.1 堆栈段 99
6.5 过程活动记录 100
6.6 关键词auto和static 103
6.7 栈框架 104
6.8 控制线程 104
6.9 setjmp和longjmp 104
6.10 UNIX下的栈段 106
6.11 MS-DOS下的栈段 106
6.12 有用的C工具 107
6.13 轻松一刻——在普林斯顿出现的编程难题 111
第七章 内存管理 114
7.1 Intel 80x86系列 114
7.2 Intel 80x86内存模式及其沿革 118
7.3 虚拟存储器 121
7.4 高速缓冲存储器 124
7.5 数据段和堆 126
7.6 内存漏洞 128
7.6.1 如何检测内存漏洞 129
7.7 总线错 131
7.7.1 总线错误 132
7.7.2 段缺失 133
第八章 为什么程序员不能区分圣诞节与万圣节前夜 139
8.1 重量与计量的PotrZebie系统 139
8.2 从位模式建造图标 140
8.3 类型在等待中改变 142
8.4 原型的麻烦 144
8.4.1 原型何处失败 145
8.5 不换行取字符 147
8.6 用C实现有穷状态自动机 151
8.7 软件比硬件更困难 152
8.8 如何及为什么投影 154
8.9 轻松一刻——令人困惑的C代码国际竞赛 156
第九章 再论数组 167
9.1 什么时候数组是指针 167
9.2 为什么会产生混淆 168
9.2.1 规则1:一个“表达式中的数组名”是一个指针 170
9.2.2 规则2:C把数组下标当作指针位移处理 170
9.2.3 规则3:一个“作为函数参数的数组名”是一个指针 172
9.3 为什么C把数组参数当指针处理 172
9.3.1 一个数组参数是如何引用的 173
9.4 片变址 175
9.5 数组和指针可互换性概览 175
9.6 C有多维数组 176
9.6.1 其它语言称它们为“数组的数组” 176
9.7 如何把多维数组拆开成组元 178
9.8 数组在内存中是如何排放的 179
9.9 如何初始化数组 179
9.10 轻松一刻——硬件/软件平衡 181
第十章 再论指针 184
10.1 多维数组的排放 184
10.2 指针数组 185
10.3 在数组不规则时使用指针 188
10.4 将一个一维数组传递给函数 191
10.5 用指针给函数传递多维数组 191
10.6 用指针方法从函数返回一个数组 194
10.7 用指针建立和使用动态数组 195
10.8 轻松一刻——程序证明的局限性 199
第十一章 熟悉了C,C++就容易了! 203
11.1 面向对象的程序设计 203
11.2 抽象——提取出某个事物的本质特征 205
11.3 封装——把相关类型、数据和函数组装起来 206
11.4 表示某个类——给予用户定义类型和预定义类型同样的特权 208
11.5 可用性(availability) 208
11.6 说明 209
11.7 如何调用一个方法 211
11.8 构造函数和析构函数 211
11.9 继承——重新使用已定义的操作 213
11.10 多继承——从两个或两个以上的基类派生 215
11.11 重载——不同类型上的相同行为具有同一个名字 216
11.12 C++如何进行运算符重载 217
11.13 C++中的输入/输出 217
11.14 多态性——运行时绑定 218
11.15 解释 219
11.16 C++如何实现多态性 220
11.17 多态性的使用 221
11.18 C++的其它方面 221
11.19 如果我要到那儿,我不会从这儿开始 223
11.20 它虽然过分复杂,但却是唯一的选择 224
11.21 轻松一刻——死去计算机协会 227
11.22 最后的休息——你的成绩证书 229
11.23 进一步阅读 229