第一部分 编程问题与原则 2
第1章 美的设计 2
1.1 美学观点 2
1.2 代码可读 2
1.3 适用范围 3
第2章 代码质量 4
2.1 外在特性 4
2.2 内在特性 4
2.3 一个故事 5
2.4 提升质量 5
第3章 代码问题 7
3.1 最混乱的 7
3.2 命名混乱 8
3.3 名实不副 8
3.4 格式混乱 9
3.5 注释混乱 9
3.6 重复冗余 9
3.7 臃肿庞大 9
3.8 晦涩难懂 10
3.9 过度耦合 10
3.10 滥用变量 10
3.11 嵌套太深 10
3.12 代码混杂 10
3.13 不确定性 11
3.14 太多警告 11
3.15 鸡同鸭讲 11
3.16 过度设计 11
3.17 基础不好 11
3.18 陈旧腐败 12
3.19 停滞不前 12
3.20 不可扩充 12
3.21 最后总结 12
第4章 人员问题 13
4.1 思维定势 13
4.2 思维顽固 14
4.3 小中见大 14
4.4 懒虫心理 14
4.5 粗枝大叶 15
4.6 巧合编程 15
4.7 应付差事 15
4.8 固步自封 15
4.9 疲惫不堪 15
4.10 环境混乱 16
4.11 管理失职 16
4.12 个人性格 16
第5章 编程原则 17
5.1 高内聚低耦合 17
5.2 设计模式 18
5.3 编码风格 19
5.4 干干净净 20
第6章 编程之道 21
6.1 注重质量 21
6.2 遵守规则 22
6.3 简洁编程 22
6.4 整洁编程 23
6.5 快乐编程 24
6.6 团队协作 25
6.7 测试驱动 25
6.8 考虑全局 25
6.9 代码切分 26
6.10 代码重构 26
6.11 深入学习 27
6.12 寻求诗意 27
6.13 程序员节 28
第二部分 编程格式与风格 30
第7章 使用Emacs 30
7.1 Emacs介绍 30
7.2 Emacs安装 31
7.3 常用快捷键 31
7.4 笔者的“.emacs” 32
7.5 cua-mode 33
7.6 shell buffer 34
第8章 快速排序 35
8.1 算法简介 35
8.2 C/C++语言 35
8.3 Java 36
8.4 Perl 36
8.5 Verilog 37
第9章 格式优美 39
9.1 合理安排 39
9.2 横向缩进 40
9.3 纵向对齐 43
9.4 顺序书写 44
9.5 分组成块 45
9.6 添加空白 46
9.7 书写语句 47
9.8 书写表达式 47
9.9 Verilog部分 48
9.10 保持一致 49
9.11 代码例子 50
第10章 注释合理 52
10.1 无用的注释 52
10.2 有用的注释 58
10.3 如何写注释 62
第11章 名字定义 65
11.1 命名方法 65
11.2 命名 67
11.3 命名规则 73
11.4 名字使用 77
11.5 SPEC定义 77
第三部分 让代码更容易读 84
第12章 消除警告 84
12.1 不可忽视 84
12.2 警告类型 86
12.3 打开警告 87
第13章 精心用变量 89
13.1 修改变量的名字 89
13.2 进行变量初始化 90
13.3 减少变量的个数 91
13.4 缩小变量作用域 92
13.5 减少变量的操作 95
第14章 表达式易读 96
14.1 糟糕的表达式 96
14.2 使用中间变量 96
14.3 使用等价逻辑 98
14.4 简化判断逻辑 98
14.5 使用宏定义 99
14.6 使用查找表 99
14.7 注意操作符 101
14.8 简洁的写法 102
第15章 控制流易读 104
15.1 组织直线型代码 104
15.2 判断中的表达式 105
15.3 判断中的注意事项 105
15.4 判断中的参数顺序 106
15.5 判断中的赋值语句 106
15.6 if语句的逻辑顺序 107
15.7 使用“?:” 108
15.8 使用switch 108
15.9 使用return 109
15.10 选择for/while 109
15.11 少用do/while 110
15.12 少用goto 112
15.13 语句对比 113
15.14 减少嵌套 114
15.15 减少代码 117
第16章 设计好函数 119
16.1 不好的函数 119
16.2 好的函数 119
16.3 小的函数 120
16.4 递归调用 121
第四部分 如何做代码重构 124
第17章 代码重构 124
17.1 为什么重构 124
17.2 重构的好处 124
17.3 重构的难题 125
17.4 实际的例子 125
第18章 消除重复 128
18.1 代码重复的产生 128
18.2 代码重复的后果 128
18.3 代码重复的解决 129
18.4 消除重复的例子 129
第19章 代码切分 133
19.1 抽取独立的代码 133
19.2 设计通用的代码 135
19.3 简化已有的接口 137
19.4 一次只做一件事 138
19.5 让函数功能单一 142
19.6 删除无用的代码 144
第20章 少写代码 145
20.1 合适就刚刚好 145
20.2 保持代码简洁 145
20.3 使用循环解决 146
20.4 熟悉语言特性 147
20.5 熟悉库函数 147
20.6 熟悉系统工具 149
第21章 简化代码 150
21.1 重新设计代码 150
21.2 寻找更好算法 152
第22章 代码生成 155
22.1 配置Linux的内核 155
22.2 生成寄存器的代码 156
22.3 生成Benes的代码 157
第23章 代码测试 161
23.1 测试中问题 161
23.2 测试的原则 162
23.3 设计要更好 162
23.4 提高可读性 162
23.5 测试智能化 164
23.6 定位Bug 167
第五部分 C语言一些要素 170
第24章 关键字 170
第25章 类型 172
25.1 内部数据类型 172
25.2 新增数据类型 173
25.3 enum 173
25.4 struct 174
25.5 union 175
25.6 typedef 175
25.7 复杂的数据类型 177
25.8 Endian问题 177
第26章 变量 179
26.1 声明和定义 179
26.2 变量分类 179
26.3 const变量 183
26.4 volatile变量 185
26.5 混合声明 187
第27章 常量 188
27.1 常量类型 188
27.2 常量定义 189
27.3 常量区分 189
27.4 其他问题 189
第28章 操作 190
28.1 操作符表格 190
28.2 操作符解释 192
28.3 强制进行类型转换 199
28.4 运算时的类型转换 199
28.5 赋值时的类型转换 203
第29章 数组 206
29.1 数组的说明 206
29.2 初始化 206
29.3 字符串 207
29.4 复合常量赋值 208
29.5 函数中的变长数组 208
29.6 结构中的灵活数组 209
29.7 数组作为函数参数 209
29.8 数组和指针 210
第30章 指针 212
30.1 指针的说明 212
30.2 啰嗦的指针 213
30.3 void 214
30.4 restrict 215
30.5 多级指针 216
30.6 数组指针和指针数组 217
30.7 函数指针和指针函数 219
30.8 malloc 222
30.9 alloca 223
30.10 指针使用中的问题 223
第31章 语句 225
31.1 if 225
31.2 switch 225
31.3 for和while 226
31.4 do{...}while 226
31.5 break 227
31.6 return 228
31.7 goto 228
31.8 exit() 229
31.9 复合语句 229
30.10 空语句 229
第32章 函数 231
32.1 void 231
32.2 static 231
32.3 inline 231
32.4 函数原型 232
32.5 参数可变 233
32.6 其他讨论 234
第33章 库函数 235
33.1 使用getopt() 235
33.2 使用qsort() 236
33.3 文件模式问题 236
33.4 返回值的问题 238
33.5 控制字符问题 238
33.6 缓冲区问题 239
33.7 可重入问题 240
第34章 预处理 242
34.1 文件包含 242
34.2 宏定义 244
34.3 条件编译 248
34.4 其他命令 249
34.5 预处理输出 249
第35章 错误处理 250
35.1 错误检查和处理 250
35.2 封装函数 250
35.3 使用断言 251
第36章 内存映像 254
36.1 程序编译后的section 254
36.2 程序运行时的内存空间 255
36.3 简单的malloc.c 255
第37章 汇编语言 258
37.1 如非必要 258
37.2 熟悉ABI 259
37.3 汇编例子 259
第38章 GCC特色 261
38.1 MinGW 261
38.2 执行过程 262
38.3 内嵌汇编 262
38.4 attribute 264
参考文献 266