《C语言程序设计进阶教程》解读了栈、堆、表针、文档等各种程序编写定义和数据结构以及运用,根据比照程序编写中的普遍不正确与恰当的程序流程中间的差别来提升用户的程序编写专业技能,详细介绍怎样变成程序猿的工作经验和方法。特别是在是这书将离散数学中的有关定义与编程设计密不可分相接,细腻地论述递归程序流程的观念、保持和运用,使用户可以从这当中习得大量专业知识,把握高級程序编写方法。这书可做为高等学校c语言有关课程内容的本科毕业教材内容,也可做为中等水平程序编写水准的大学生提高程序编写专业技能的教材。
Yung-Hsiang Lu(陆永祥),现为普度大学电子器件和电子计算机工程学校副教授职称。他是ACM优秀生物学家和优秀讲者, IEEE重新启动测算方案(Rebooting Computing initiative)组员。他還是2015年第一届功耗图像识别技术比赛的关键策划者,IEEE多媒体通信技术性联合会的多媒体通信系统软件兴趣爱好组的现任主席(2014-2016)。他2002年得到了斯坦福学校电子器件工程系博士研究生。
目录
- 出版者的话
- 译者序
- 序
- 前言
- 第一部分 计算机存储:内存和文件
- 第1章 程序的执行 2
- 1.1 编译 2
- 1.2 重定向输出 6
- 第2章 栈内存 7
- 2.1 值和地址 7
- 2.2 栈 8
- 2.3 调用栈 9
- 2.3.1 返回位置 9
- 2.3.2 函数实参 12
- 2.3.3 局部变量 14
- 2.3.4 值地址 15
- 2.3.5 数组 16
- 2.3.6 获取地址 17
- 2.4 可见度 17
- 2.5 习题 20
- 2.5.1 绘制调用栈I 20
- 2.5.2 绘制调用栈II 20
- 2.5.3 地址 21
- 2.6 习题解答 21
- 2.6.1 绘制调用栈I 21
- 2.6.2 绘制调用栈II 22
- 2.6.3 地址 22
- 2.7 在DDD(命令行调试程序)上检测调用栈 22
- 第3章 预防、检测及消除bug 26
- 3.1 开发软件≠编码 26
- 3.1.1 编程前 26
- 3.1.2 编程中 27
- 3.1.3 编程后 28
- 3.2 常见错误 28
- 3.2.1 未初始化变量 28
- 3.2.2 错误数组下标 28
- 3.2.3 错误数据类型 28
- 3.3 后执行式和交互式调试 28
- 3.4 生产代码与测试代码分离 29
- 第4章 指针 30
- 4.1 作用域 30
- 4.2 swap函数 31
- 4.3 指针 33
- 4.4 再论swap函数 37
- 4.5 类型错误 39
- 4.6 数组和指针 40
- 4.7 类型规则 43
- 4.8 指针运算 44
- 4.9 习题 47
- 4.9.1 swap函数1 47
- 4.9.2 swap函数2 48
- 4.9.3 swap函数3 48
- 4.9.4 swap函数4 48
- 4.9.5 swap函数5 49
- 4.9.6 15 552种变化 49
- 4.10 习题解答 50
- 4.10.1 swap函数1 50
- 4.10.2 swap函数2 50
- 4.10.3 swap函数3 51
- 4.10.4 swap函数4 51
- 4.10.5 swap函数5 51
- 第5章 编写和测试程序 52
- 5.1 不同的数组元素 52
- 5.1.1 main函数 52
- 5.1.2 areDistinct函数 53
- 5.1.3 编译和链接 54
- 5.1.4 make工具 55
- 5.2 使用Makefile测试 57
- 5.2.1 生成测试用例 58
- 5.2.2 重定向输出 58
- 5.2.3 使用diff去比较输出 58
- 5.2.4 添加测试到Makefile 59
- 5.3 无效的内存访问 60
- 5.4 使用valgrind检查内存访问错误 62
- 5.5 测试覆盖 64
- 5.6 限制内核大小 67
- 5.7 带有死循环的程序 67
- 第6章 字符串 69
- 6.1 字符数组 69
- 6.2 C语言中的字符串函数 72
- 6.2.1 复制函数:strcpy 72
- 6.2.2 比较函数:strcmp 73
- 6.2.3 寻找子字符串函数:strstr 73
- 6.2.4 寻找字符函数:strchr 74
- 6.3 理解argv 74
- 6.4 对子字符串计数 77
- 第7章 编程问题和调试 80
- 7.1 实现字符串函数 80
- 7.1.1 C语言库 80
- 7.1.2 头文件 80
- 7.1.3 mystring.h 82
- 7.1.4 创建输入和正确输出 82
- 7.1.5 Makefile 86
- 7.1.6 mystring.c 86
- 7.1.7 使用const 88
- 7.2 调试 89
- 7.2.1 找到死循环 90
- 7.2.2 找到无效内存访问 91
- 7.2.3 检测无效内存访问 92
- 第8章 堆内存 94
- 8.1 用malloc函数创建数组 94
- 8.2 栈和堆 96
- 8.3 返回堆地址的函数 98
- 8.4 C语言中的二维数组 99
- 8.5 指针和参数 101
- 第9章 使用堆内存的编程问题 104
- 9.1 对数组排序 104
- 9.1.1 生成测试输入和期望输出 104
- 9.1.2 重定向输入 105
- 9.1.3 整数排序 107
- 9.1.4 使用valgrind检测内存泄漏 110
- 9.2 使用qsort进行排序 111
- 9.2.1 qsort 111
- 9.2.2 比较函数 112
- 9.2.3 执行范例 114
- 9.2.4 对字符串排序 115
- 第10章 读写文件 118
- 10.1 通过argv传递一个文件名 118
- 10.2 读取文件 119
- 10.2.1 读取字符型:fgetc 119
- 10.2.2 读取整型:fscanf(...%d...) 121
- 10.3 写入文件 123
- 10.4 读写字符串 125
- 第11章 编程解决使用文件的问题 128
- 11.1 对文件中的整数进行排序 128
- 11.2 计算字符出现的次数 130
- 11.3 计算单词出现的次数 132
- 11.4 如何注释程序 134
- 第二部分 递归
- 第12章 递归 138
- 12.1 在限制条件下选取小球 138
- 12.1.1 双色球问题 138
- 12.1.2 三色球问题 139
- 12.1.3 附加限制条件 140
- 12.2 单行道 142
- 12.3 汉诺塔 143
- 12.4 计算整数分拆 145
- 12.4.1 计算“1”的个数 147
- 12.4.2 仅使用奇数进行分拆 148
- 12.4.3 使用递增数进行分拆 148
- 12.4.4 交替使用奇偶数进行分拆 149
- 12.4.5 整数分拆问题的推广 151
- 12.4.6 解决分拆问题的错误方法 151
- 第13章 递归函数 152
- 13.1 在限制条件下选取小球 152
- 13.2 单行道 155
- 13.3 汉诺塔 156
- 13.4 整数分拆 158
- 13.5 阶乘 159
- 13.6 斐波那契数列 161
- 13.7 利用gprof进行性能分析 165
- 第14章 整数分拆 167
- 14.1 堆内存和栈内存 168
- 14.2 追踪递归函数调用 176
- 14.3 约束条件下的分拆 178
- 14.3.1 仅使用奇数进行分拆 179
- 14.3.2 使用递增数进行分拆 179
- 14.3.3 交替使用奇偶数进行分拆 180
- 14.3.4 使用gprof和gcov查找性能瓶颈 180
- 第15章 使用递归解决问题 187
- 15.1 二分搜索 187
- 15.2 快速排序 189
- 15.3 排列组合 195