第一篇 C语言编程中的对与错 2
第1章 初涉C语言者的困惑 2
1.1 中文字符以假乱真 2
1.2 象形字体扰乱视听 3
1.3 都是注释惹的祸 4
1.4 千万不要忘记我 4
1.5 别把分号放错地方 4
1.6 少了花括号就是行不通 6
1.7 scanf要“&”不要“\n” 6
1.8 老大就是要在最前面 6
1.9 记住我就会受益无穷 7
第2章 用好printf和scanf一对活宝 9
2.1 printf输出的小奥妙 9
2.2 printf输出整数或字符 11
2.3 输入的格式配对错误 12
2.4 空格让scanf莫名其妙 14
2.5 回车键打乱scanf的阵脚 15
2.6 字符输入要搞特殊化 15
2.7 别混淆字符数组和字符 17
2.8 一维数组更要特殊对待 19
2.9 输出值的操作符 20
2.10 引入指针更方便 23
2.11 指针的困惑 24
第3章 基本数据类型 26
3.1 混合运算要小心 26
3.2 数据类型的后缀符号 28
3.3 基本数据的初始化 28
3.4 注意编译系统的差别 29
3.5 不要用错等于运算符 30
3.6 不要用错逗号运算符 31
第4章 程序控制语句 34
4.1 控制流程运算容易出现的问题 34
4.1.1 写错关系运算符 34
4.1.2 混淆表达式和关系表达式的值 36
4.1.3 混淆逻辑表达式和逻辑表达式的值 37
4.1.4 混淆逻辑运算符和位运算符 38
4.2 程序控制语句容易出现的问题 39
4.2.1 条件分支语句的错误 39
4.2.2 控制重复的分支语句 44
4.2.3 运算符优先级错误 53
4.2.4 求值顺序 55
第5章 数组与指针是重点 58
5.1 一维数组越界和初始化错误 58
5.1.1 一维数组越界错误 58
5.1.2 一维数组初始化错误 60
5.2 数组赋值错误 61
5.3 指针地址的有效性 64
5.4 配合使用一维数组与指针 69
5.4.1 使用一维数组名简化操作 69
5.4.2 使用指针操作一维数组 71
5.4.3 使用一维字符数组 78
5.4.4 不要忘记指针初始化 79
5.5 多维数组与指针 81
5.5.1 数组操作及越界和初始化错误 81
5.5.2 二维数组与指针 85
5.5.3 二维数组与指向一维数组的指针 89
第6章 函数是核心 91
6.1 函数的声明与定义 91
6.2 函数变量的作用域 93
6.3 函数变量类型的匹配 95
6.4 函数的返回路径 95
6.5 函数参数的设计及传递 96
6.6 传递指针不一定改变原来参数的值 98
6.7 函数的返回值 99
6.7.1 无返回值的void类型函数 100
6.7.2 函数返回值问题 102
第7章 宏与const 106
7.1 用const代替无参数的宏定义 106
7.2 有参数的宏定义 109
第8章 库函数 112
8.1 引用的库函数与头文件不匹配 112
8.2 与库函数的参数类型不匹配 113
8.3 对库函数的作用理解不对 114
8.4 充分利用库函数printf的功能 118
8.4.1 printf的函数原型 119
8.4.2 printf函数的格式控制符 120
第9章 结构 134
9.1 结构定义和赋值错误 134
9.2 结构作为函数参数及函数的返回值 140
9.3 使用结构数组和指针容易出现的错误 145
9.4 其他注意事项 147
第10章 联合与枚举 148
10.1 联合 148
10.2 枚举 153
第11章 状态机 159
第二篇 C语言编程中的好与坏 170
第12章 注意编译系统的差别 170
12.1 打开所有编译开关 170
12.2 克服依靠编译系统产生的错误 170
第13章 测试与调试程序 174
13.1 预防措施 174
13.1.1 书写格式和注意事项 174
13.1.2 命名注意事项 176
13.1.3 程序注释 178
13.2 使用条件编译 180
13.3 消灭警告信息 183
13.4 使用简单的输出信息调试程序 185
13.5 编写error函数 194
13.6 使用集成环境提供的调试手段 197
13.6.1 一个简单的实例 197
13.6.2 编译程序 198
13.6.3 排错 199
13.6.4 基本调试命令简介 200
13.6.5 程序与汇编调试窗口 203
13.7 调试程序实例 204
13.8 软件测试 206
13.8.1 模块测试 209
13.8.2 组装测试 211
13.8.3 确认测试 211
13.9 程序的测试与调试 212
13.10 测试用例设计技术 214
13.10.1 逻辑覆盖法 215
13.10.2 等价划分法 218
13.10.3 边值分析法 219
13.10.4 因果图法 219
13.10.5 错误猜测法 220
第14章 正确使用变量、常量和指针 221
14.1 基本数据类型的变量初始化 221
14.2 不要混淆字符和字符串 222
14.3 指针的初始化 224
14.4 指针相等 228
14.5 使用const 232
14.5.1 左值和右值 232
14.5.2 推荐使用const定义常量 234
14.5.3 对函数传递参数使用const限定符 236
14.5.4 对指针使用const限定符 237
14.6 使用volatile变量 240
14.7 变量的存储地址分配 242
第15章 正确使用宏 246
15.1 不要使用不存在的运算符 246
15.2 正确使用定义的宏 247
15.3 正确定义宏的参数 248
15.4 使用宏定义函数 250
第16章 控制语句 252
16.1 运算顺序错误 252
16.2 采用更明确的条件 254
16.3 设计存在的问题 256
16.3.1 没有涵盖全部条件 256
16.3.2 条件超出范围 261
16.3.3 减少循环次数 264
16.4 正确选择运算符 273
16.5 优先级和求值顺序错误 277
第17章 位运算 285
17.1 位运算典型错误 285
17.2 位运算典型实例 290
第18章 再论数组与指针 295
18.1 一维数值数组和指针 295
18.1.1 使用数组偏移量造成数组越界 295
18.1.2 使用数组名进行错误运算 296
18.1.3 错误使用数组下标和指向数组指针的下标 298
18.1.4 小结 299
18.2 一维字符数组和指针 301
18.2.1 字符数组的偏移量 301
1 8.2.2 字符数组不对称编程综合实例 303
18.3 动态内存 307
18.3.1 非数组的指针 307
18.3.2 NULL指针 309
18.4 二维数组和指针 310
18.4.1 二维数组的界限 310
18.4.2 二维数组的一维特性 312
18.4.3 指向二维数组的指针 314
18.5 数组和指针应用实例 318
第19章 再论函数 325
19.1 函数变量的作用域 325
19.1.1 块结构之间的变量屏蔽规则 325
19.1.2 程序和文件内的变量 328
19.1.3 多文件变量作用域 331
19.2 函数的参数 337
19.2.1 完璧归赵 338
19.2.2 多余的参数 340
19.2.3 传递的参数与函数参数匹配问题 342
19.2.4 等效替换参数 345
19.3 函数的类型和返回值 347
19.3.1 函数的类型力求简单 347
19.3.2 实参要与函数形参的类型匹配 349
19.3.3 正确设计函数的返回方式 351
19.3.4 正确设计和使用函数指针 356
19.3.5 如何解读函数声明 361
第20章 再论库函数 365
20.1 getchar函数的返回类型不是字符 365
20.2 setbuf函数与其他函数的配合 368
20.3 错误使用errno函数 377
20.4 模拟设计printf函数 379
20.4.1 具有可变参数的函数 379
20.4.2 设计简单的打印函数 382
20.4.3 利用宏改进打印函数 387
20.5 scanf和sscanf函数 392
20.5.1 sscanf函数的使用方法 394
20.5.2 sscanf函数用法举例 395
20.6 探讨printt函数 398
第21章 再论结构 400
21.1 同类型结构变量之间的整体赋值 400
21.2 使用键盘赋值 405
21.2.1 为结构变量赋值 405
21.2.2 为结构指针变量赋值 407
21.2.3 为链表赋值 411
21.2.4 为结构数组的变量赋值 412
21.2.5 为含有指针域的结构数组赋值 413
21.3 使用结构作为函数的参数 417
21.3.1 结构变量的传数值与传地址值 417
21.3.2 结构数组传地址值 418
21.4 结构函数的返回值 421
21.5 修改传递的结构参数的值 430
21.6 优先使用结构指针传递参数 435
第22章 使用文件常见错误分析 439
22.1 文件的打开与关闭 439
22.2 文件的读写 450
22.3 其他读写函数 464
22.4 文件的定位 467
22.5 操作出错检测及错误标志的复位 469
22.6 文件的内存分配 470
22.7 小结 470
第23章 多文件编程 472
23.1 多文件编程错误浅析 472
23.2 单文件结构 475
23.3 一个源文件和一个头文件 475
23.4 多文件结构 477
第24章 发布C程序 483
24.1 两种版本的异同 483
24.2 两种版本的设置 484
第25章 典型问题 486
25.1 计算机解题具有多解的特点 486
25.2 应对算法进行优化 487
25.3 优化时要避免出现新的错误 488
25.4 扩展程序要注意是否满足全部条件 494
25.5 注意函数设计的多样化和效率 496
25.6 使用多文件编程 502
25.7 使用状态机设计程序 507
附录A C语言操作符的优先级 513
附录B 简化优先级记忆口诀 515
附录C 7位ASCII代码表 517
主要参考文献 518