但卑意欲少年为学者, 每一书皆作数过尽之. 书富如入海, 百货皆有, 人之精力, 不能兼收尽取, 但得其所欲求者尔. 故愿学者每次作一意求之. 如欲求古今兴亡治乱、圣贤作用、但作此意求之, 勿生余念. 又别作一次, 求事迹故实典章文物之类, 亦如之. 他皆仿此. 此虽迂钝, 而他日学成, 八面受敌, 与涉猎者不可同日而语也
———— 苏轼, 又答王庠书
Chapter 1
Exercises
[x] 1-7 编写一个打印EOF的程序
[x] 1-11 你准备如何测试单词计数程序?如果程序中存在某种错误,那么什么样的输入最可能发现这类错误呢?
[ ] 1-13 编写一个程序,打印输入中单词长度的直方图。水平直方图比较容易绘制,垂直方向的直方图则要困难一些。
[ ] 1-14 编写一个程序,打印输入中各个字符出现频度的直方图。
[ ] 1-16 修改打印最长文本的程序的主程序main,使之可以打印任意长度的输入行的长度,并尽可能多地打印文本。
[ ] 1-18 编写一个程序,删除输入中每行末尾的空格和制表符,并删除完全为空的行。
[ ] 1-20 编写程序detab,将输人中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止位的地方。假设制表符终止位的位置是固定的,比如每隔n列就会出现一个制表符终止位。n应该作为变量还是符号常量呢?
[ ] 1-21 编写程序entab,将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变。假设制表符终止位的位置与练习1-20的detab程序的情况相同。当使用一个制表符或者一个空格都可以到达下一个制表符终止位时,选用哪一种替换字符比较好?
[ ] 1-22 编写一个程序,把较长的输入行“折”成短一些的两行或多行,折行的位置在输入行的第n列之前的最后一个非空格之后。要保证程序能够智能地处理输入行很长以及在指定的列前没有空格或制表符时的情况。
[ ] 1-23 编写一个删除C语言程序中所有的注释语句。要正确处理带引号的字符串与字符常量。在C语言中,注释不允许嵌套。
[ ] 1-24 编写一个程序,查找C语言程序中的基本语法错误,如圆括号、方括号、花括号不配对等。要正确处理引号(包括单引号和双引号)、转义字符序列与注释。(如果读者想把该程序编写成完全通用的程序,难度会比较大。)
Mistakes
int result[10] = 0; // 错误,不能将数组赋值为一个整数
int result[10] = {0}; // 正确,初始化数组的所有元素为0
开始进入一个单词的正确方式是在state = OUT时,遇到了第一个非空白字符
在子函数内部定义的数组,不应该将其返回给调用函数,会导致野指针问题。并且不要忘了初始化。
sizeof 是运算符(operator),不是函数,也不是宏。它在编译时计算类型或变量所占的字节数。
Chapter 2
Exercises
[ ] 2-6 编写一个函数setbits(x, p, n, y),该函数返回对x执行如下操作后的值:将x中从第p位开始的n个位(二进制)设置为y中最右边的n位,x的其余位保持不变。
[ ] 2-7 编写一个函数invert(x, p, n),该函数返回对x执行如下操作后的值:将x中从第p位开始的n个位取反,x的其余位保持不变。
Mistakes
3-1.
4-0, 4-3, 4-6, 4-7, 4-14.
5-5, 5-10, 5-13, 5-14, 5-15, 5-16, 5-17, 5-18, 5-20.
6-2, 6-3, 6-4, 6-5, 6-6.
7-3, 7-4, 7-9.
8-1, 8-2, 8-3, 8-4, 8-6, 8-7, 8-8.