关于本书 1
如何使用这本指南 1
符号约定 2
相关文档 3
其它参考资料 5
第1章 使用编程工具 6
1.1 创建源代码 6
1.2 将代码存档 8
1.3 分析代码 9
1.3.1 使用cb 10
1.3.2 使用cscope 10
1.3.3 使用lint 12
1.3.4 使用cflow 12
1.3.5 使用cxref 13
1.4 将分析过程中所做的修改归档 15
1.5 编译代码 15
1.5.1 使用make 16
1.6 测试代码 17
1.7 调试代码 18
1.7.1 使用dbxtra 18
1.7.2 测试修正的结果 22
1.8 程序结构和指导方针 22
1.8.1 程序结构 23
1.8.2 前导文件 26
1.8.3 出错处理 26
第2章 C编译系统 27
2.1 编译和链接 27
2.1.1 基本cc命令行语法 29
2.1.2 cc命令行选项的一般使用 32
2.1.3 链接 33
2.2库和前导文件 48
2.2.1 前导文件 48
2.2.2 如何使用库函数 49
2.2.3 C库(libc) 51
2.2.4 数学库(libm) 55
2.2.5 常规库(libgen) 56
2.2.6 标准I/O 58
第3章 C语言编译程序 63
编译模式 63
翻译阶段 64
3.1.2 标识符 65
3.1.3 关键字 65
3.1.1 记号 65
3.1 源文件和单词化 65
3.1.4 常量 66
3.1.5 字符串正文 68
3.1.6 宽字符串正文 68
3.1.7 标点 68
3.1.8 注释 69
3.2 预处理 69
3.2.1 三字符序列 69
3.2.2 预处理单词 69
3.2.3 预处理指令 70
3.3 声明和定义 75
3.3.1 基本类型 75
3.3.2 作用域 77
3.3.3 存储持续时间 78
3.3.4 存储类型说明 78
3.3.5 声明 79
3.3.6 函数定义 81
3.4 转换和表达式 82
3.4.1 隐含转换 82
3.4.2 表达式 83
3.4.3 操作符 84
3.4.4 操作符的结合性和优先级 89
3.4.5 常量表达式 89
3.4.6 初始化 90
3.5.3 选择语句 92
3.5.2 复合语句 92
3.5.1 表达式语句 92
3.5 语句 92
3.5.4 循环语句 93
3.5.5 跳转语句 94
3.6 可移植性考虑 95
第4章 COFF链接编辑程序 97
4.1 段 97
4.2 存储器配置 98
4.2.1 地址 98
4.2.2 连接 98
4.2.3 目标文件 98
4.3 链接编辑程序的命令语言 99
4.3.1 表达式 99
4.3.2 赋值语句 100
4.3.3 指向存储器配置 101
4.3.4 段定义指令 103
4.4 改变入口点 111
4.5 使用归档库 112
4.6 分配算法 113
4.6.1 增量链接编辑 114
4.6.2 DSECT,COPY,NOLOAD,INFO和OVERLAY段 115
4.6.3 输出文件分块 116
4.6.4 不可重定位输入文件 116
4.7 输入指令语法图 117
第5章 lint分析程序 121
5.1 lint做些什么 122
5.1.1 一致性检查 122
5.1.2 可移植性检查 123
5.1.3 可疑的结构 124
5.2 使用lint 125
5.2.1 lint库 126
5.2.2 lint过滤程序 127
5.2.3 选项和指令 127
5.3 理解“lint-特有”的消息 131
第6章 dbXtra和dbxtra 156
6.1 从命令行调用dbXtra和dbxtra 156
6.2 dbXtra界面 157
6.2.1 配置dbXtra X11和Motif资源 159
6.3 dbxtra界面 159
6.3.1 屏幕方式 160
6.3.2 dbxtra键盘接口 161
6.4 dbxtra辅导 166
6.4.1 为dbxtra准备文件 166
6.4.3 dbxtra屏幕 167
6.4.2 启动dbxtra 167
6.4.4 dbxtra求助机制 168
6.4.5 打印变量值 168
6.4.6 查看源代码和别名 168
6.4.7 查看调用栈 169
6.4.8 遍历调用栈 169
6.4.9 监视变量内容 169
6.4.10 分析结果 170
6.4.11 检查不同函数 170
6.4.12 使用断点 171
6.4.13 从断点后继续执行 171
6.5.2 Events选单:管理执行时事件 172
6.5.1 File选单:保存和退出 172
6.5 dbXtra 和dbxtra命令 172
6.4.14 退出dbxtra 172
6.5.3 eXecute选单:执行被调试程序 178
6.5.4 Source选单:存取源文件 180
6.5.5 Info选单:调试寄存器、存储单元和表达式 181
6.5.6 Options选单:控制调试环境 183
6.5.7 help选单 185
6.5.8 curese界面命令 185
6.5.9 默认命令别名 187
6.5.10 dbXtra和dbxtra表达式和条件 187
6.6 C++专用调试特性 189
6.6.1 使用需求 189
6.6.2 重载的函数和操作符 189
6.6.3 dbXtra和dbxtra cc命令 190
6.6.4 调试子进程 191
6.7 连接到运行进程 192
第7章 sdb:符号调试程序 193
7.1 使用sdb 193
7.1.1 以一个程序文件启动sdb 193
7.1.2 以一个内存映像启动sdb 194
7.1.3 显示一个栈的轨迹 195
7.1.4 诊断变量 195
7.1.5 规定变量格式 196
7.2 显示和操作源文件 197
7.2.1 显示源文件 197
7.3 控制程序的执行 198
7.3.1 设置和删除断点 198
7.3.2 程序的单步跟踪 199
7.3.4 调用函数和过程 200
7.3.3 运行程序 200
7.4 调试机器语言程序 201
7.4.1 显示机器语言语句 201
7.4.2 寄存器操作 201
7.5 其它命令 201
7.6 样本sdb对话 202
第8章 adb调试程序 205
8.1 启动adb 205
8.1.1 使用程序文件启动 205
8.1.2 使用内存映像文件启动adb 206
8.1.3 退出adb 206
8.2 显示指令和数据 207
8.2.1 形成地址 207
8.2.2 形成表达式 207
8.2.3 选择数据格式 211
8.2.5 使用“?”和“/”命令 213
8.2.4 使用“=”命令 213
8.2.6 一个例子:简单格式化 214
8.3 调试程序执行 215
8.3.1 执行一个程序 215
8.3.2 设置断点 216
8.3.3 显示断点 216
8.3.4 继续执行 217
8.3.5 使用中断键和退出键停止程序 217
8.36 单步执行程序 217
8.3.9 显示C栈回溯 218
8.3.10 显示CPU寄存器 218
8.3.8 删除断点 218
8.3.7 杀死程序 218
8.3.11 显示外部变量 219
8.3.12 一个例子:跟踪多个函数 219
8.4 使用adb内存映像 223
8.4.1 显示内存映像 223
8.4.2 改变内存映像 224
8.4.3 建立新的映像项 225
8.4.4 验证地址的合法性 225
8.5 其它特点 226
8.5.1 在一行中组合命令 226
8.5.2 建立adb命令文件 226
8.5.3 设置输出宽度 227
8.5.4 设置最大位移量 227
8.5.6 使用UNIX命令 228
8.5.7 计算数值和显示正文 228
8.5.5 设置默认输入格式 228
8.5.8 一个例子:卸出目录和i节点 229
8.6 修补二进制文件和内存 230
8.6.1 在文件中确定值的位置 230
8.6.2 写文件 231
8.6.3 修改内存 231
第9章 C程序员的效率工具 232
9.1 prof 232
9.1.1 建立程序的剖视版本 232
9.1.2 运行被补剖视的程序 233
9.1.3 PROFOPTS环境变量 233
9.1.4 使用PROFOPTS的例子 233
9.2 解释剖视输出 235
9.2.1 查看剖视源列表 236
9.2.3 lprof所需文件 238
9.2.2 为lprof指定程序和数据文件 238
9.2.4 文件子集的源列表 239
9.2.5 总计选项 239
9.2.6 归并选项 240
9.2.7 使用lprof的注意事项 240
9.2.8 使用prof和lprof提高性能 242
9.2.9 使用lprof扩大测试覆盖范围 242
9.3 cscope 244
9.3.1 配置环境 244
9.4 使用cscope 245
9.4.1 运行cscope 247
9.4.2 交叉引用文件 247
9.4.3 一个辅导例子:查找出错信息源 248
9.5.1 改变文本串 253
9.4.4 条件编辑指令 253
9.5 使用cscope的例子 253
9.5.2 函数增加实参 255
9.5.3 改变变量的值 256
第10章 make 257
10.1 基本功能 257
10.2 并行make 259
10.3 递归makefile 259
10.4 makefile和替换 260
10.4.1 依赖行语法 260
10.4.2 依赖关系信息 260
10.4.3 宏定义 261
10.4.4 可执行命令 262
10.4.5 输出转换 263
10.5.1 隐含规则 264
10.5 反缀和转换规则 264
10.5.2 归档库 266
10.5.3 SCCS文件名中的波浪线 267
10.5.4 空后缀 269
10.5.5 创建新的后缀规则 269
10.6 包含文件 270
10.7 动态依赖参数 270
10.8 环境变量 271
10.9 建议和警告 272
10.10 Makefile例子 273
10.11 内部规则 274
第11章 源代码控制系统 279
11.1 概述 279
11.2.1 文件和目录 280
11.2 基础知识 280
11.2.2 delta和SID 281
11.2.3 SCCS工作文件 282
11.2.4 文件管理员 283
11.3 建立和使用s-文件 283
11.3.1 建立s-文件 283
11.3.2 为读而复原文件 284
11.3.3 编辑和修改SCCS文件 285
11.3.4 使用多个版本 286
11.3.5 比较版本之间的差异 290
11.3.6 简化版本结构 291
11.3.7 显示s-文件 292
11.3.8 显示delta版本的信息 295
11.3.9 包含与排除delta 296
11.4 使用标识关键字 297
11.5 使用s-文件标志 300
11.6 修改s-文件信息 302
11.6.1 加入注释 302
11.6.2 修改注释 303
11.7 保护和修复s-文件 303
11.7.1 检查s-文件 305
11.7.2 修复SCCS文件 305
11.8 同时编辑一个s-文件 306
11.9 SCCS的求助功能 307
11.10 make与SCCS 307
第12章 词法分析程序的生成程序lex 310
12.1 lex的工作原理 310
12.2.1 字符的集合 311
12.2 lex源程序中的正则表达式 311
12.2.3 选择和字符组 312
12.2.4 重复和辅助定义 312
12.2.5 其它 312
12.3 lex源程序中的动作 312
12.2.2 闭包运算 312
12.4 lex源程序的格式 314
12.5 lex程序的输入和输出 316
12.6 二义性和上下文相关性的处理 319
12.6.1 二义性的处理 319
12.6.2 上下文相关性的处理 319
12.7 其它 321
12.8 常用的一些运算符 322
12.9 lex与yacc的配合使用 323
13.1 yacc的工作原理 324
第13章 编译程序的编译程序yacc 324
13.2 一个简单的例子 325
13.3 yacc源程序中的规则 328
13.4 yacc源程序中的动作 329
13.4.1 语义值的定义 330
13.4.2 复杂的语义动作 330
13.5 yacc源程序的格式 331
13.5.1 说明部分的写法 331
13.5.2 运算符优先级和结合性的定义 333
15.5.3 程序段部分的写法 334
13.6 yacc和lex的配合使用 335
13.7 yacc源程序的风格 336
13.8 对输入的进一步讨论 336
13.9 再论二义性的处理 337
13.10 语法分析中错误的处理 338
13.11 其它 339
13.12 例子 339
13.12.1 计算器hoc 339
13.12.2 计算器ec 341
13.12.3 汉语拼音流分析程序 360
第14章 共享库 372
14.1 什么是共享库 372
14.1.1 共享库例子 373
14.1.2 建立a.out文件 373
14.2 决定是否使用共享库 373
14.3 空间考虑 374
14.3.1 节省空间 374
14.3.4 标识使用共享库的a.out文件 376
14.3.2 提高内存空间的利用率 376
14.3.3 编写应用程序 376
14.3.5 调试使用共享库的a.out文件 377
14.4 实现共享库 377
14.4.1 主库和目标库 377
14.4.2 转移表 378
14.5 建立共享库 379
14.5.1 建立过程 379
14.5.2 编写共享代码的原则 382
14.6 选择库成员 382
14.6.1 包含大的、使用频繁的例程 382
14.7 改变共享库的已有代码 383
14.6.5 包含库本身所需例程 383
14.6.4 排除维护复杂的例程 383
14.6.3 排除使用很多静态数据的程序 383
14.6.2 排除不常使用的例程 383
14.7.1 将全局数据减至最少 384
14.7.2 使用说明文件实现兼容性 386
14.7.3 传入符号 387
14.7.4 提供和非共享库的兼容性 392
14.7.5 调整共享库代码 393
14.7.6 检查兼容性 394
14.7.7 示例 397
附录A ANSI定义实现的行为 404
A.1 翻译 404
A.3 标识符 405
A.2.2 交互设备 405
A.2.1 main()的实参 405
A.2 环境 405
A.1.1 识别诊断结果 405
A.3.1 无外部链接的有效字符 406
A.3.3 有外部链接的有效字符 406
A.3.3 字符大小写的意义 406
A.4 字符 406
A.4.1 源字符符集和执行字符集 406
A.4.2 每个字符的位 406
A.4.3 映像字符集 406
A.4.4 无法表示的字符常量和转义序列 407
A.4.5 多字符集常量或长字符常量 407
A.5.2 整型的降级 408
A.5.1 整型值域和表示 408
A.5 整型 408
A.4.6 用于多字节转换的规则 408
A.4.7 字符的值域 408
A.5.3 带符号的按位操作 409
A.5.4 除后余数的符号 409
A.5.5 负的有符号整数的右移位 409
A.6 浮点型 409
A.6.1 浮点型值域和表示 409
A.6.2 将整数转换为浮点数 409
A.6.3 将浮点数转变为短浮点数 410
A.7 数组和指针 410
A.7.1 最大数组长度 410
A.7.2 强制指针 410
A.7.3 指针减法 410
A.9.2 结构成员的填充与对准 411
A.9.4 分配位字段的顺序 411
A.9.3 位字段的符号 411
A.8 寄存器 411
A.9.1 非法存取联合 411
A.9 结构、联合、枚举和位字段 411
A.8.1 使用寄存器 411
A.9.5 位字段的对准 412
A.9.6 枚举类型值的类型 412
A.10 限定符 412
A.10.1 存取易失目标 412
A.11 说明符 412
A.13.3 带引号的包含文件 413
A.13.2 查找可包含的源文件 413
A.13.1 字符常量和条件包含 413
A.12.1 case值的最大数目 413
A.12 语句 413
A.11.1 说明符的最大数目 413
A.13 预处理指令 413
A.13.4 字符序列 414
A.13.5 Pragmas 414
A.13.6 定义日期和时间 415
A.14 库函数 415
A.14.1 扩展宏NULL 415
A.14.2 assert函数输出的诊断结果 416
A.14.3 测试字符 416
A.14.4 数学函数和域错误 416
A.14.5 浮点数的下溢 416
A.14.7 signal函数 417
A.14.6 作用域错误和fmod函数 417
A.14.8 默认信号 418
A.14.9 信号阻塞 418
A.14.10 SIGILL信号 419
A.14.11 终结的换行符 419
A.14.12 换行符前的空字符 419
A.14.13 将空字符追加到二进制流 419
A.14.14 追加方式中文件位置 419
A.14.15 文件缓冲 419
A.14.16 存在0长度文件 419
A.14.17 组织正确的文件名 419
A.14.23 读的范围 420
A.14.22 指针值输入 420
A.14.21 输出指针值 420
A.14.19 关闭打开的文件 420
A.14.18 文件存取限制 420
A.14.20 使用存在的名字重新命名 420
A.14.24 文件位置错误 421
A.14.25 perror函数产生的消息 421
A.14.26 分配零存储 421
A.14.27 abort函数和打开的临时文件 421
A.14.28 exit函数 421
A.14.29 环境名 421
A.14.30 System函数 421
A.14.31 strerror函数 422
A.15.2 输出方向 426
A.15.4 字符测试和大小写转换 426
A.15.3 十进制点字符 426
A.15 特殊场合特性 426
A.15.1 执行字符集的内容 426
A.14.33 clock函数 426
A.14.32 时区 426
A.15.5 理序顺序 428
A.15.6 时间和日期格式 428
A.16 C实现限制介绍 428
A.16.1 环境限制 428
A.17 翻译限制 430
附录B C编译程序诊断结果 432
B.1 消息类型和可用选项 432
B.1.1 消息中的操作符名 433
B.2 消息 433
B.4 其它出错消息 532