0. 前言:“要学好C语言,绝非熟悉语法和语义这么简单”不太正确,语言是语言,算法是算法,不能说算法厉害了才算把语言学好了(作者说如果把”学好“改成”用好“就更明白了)。
if (s >= n) {
k % 2 ? printf("%d/%d\n", s-n+1, k-s+n) :
printf("%d/%d\n", k-s+n, s-n+1);
break;
}
82页的程序也同样有此问题,改法相同。
scanf(" %c%d%d", &cmmnd, &x, &y);
完全不用费力地去用%s(作者说他也知道,不过故意使用笨方法,让学生们能快速理解并且避免在以后出错,因为他惊异于小朋友们能犯出简单语法错误的能力- -)。
for(int X = right[0]; X != n+1; X = right[X])
right[0]本来就是虚拟的小球,如果输入5 1[enter]B 3 5[enter],由于right[0]默认总是0,就会出现死循环,偶修改了多次,总会有各种各样的Bug,所以偶目前没什么好的解决方案。
11. 99页题目说如果该结点上的开关关闭,则往左走……而种种迹象表明明明是开关打开才往左走……
12. 101页作者说而一共可能有10000组数据,而99页题目上明明写着最多包含1000组数据……
13. 发现不是错误。
14. 109页中的dist在这里没有用处。
15. 115页下面的样例输出中的那个8应该改成12。
16. 116页中,根据双基回文数的题目分析,2<=b1,b2<=10应该改为:b1, b2∈[2, 10]。
以下不是错误,但需要提醒:
1. 在整本书中,作者都在printf()中对double使用%lf,这说明作者不懂C语言中的默认参数提升。因为float类型参数会被提升为double类型,所以单单有%f就是足够的,而C99考虑到了很多人并不了解这点,所以定义了与%f等价的%lf,所以你为了防止编译器不支持C99的这一特性,应该在printf()中使用%f而不是%lf。
int cmp_char(const void *a, const void *b)
{
return *(char *)a - *(char *)b;
}
6. 82页中作者说为了避免浮点误差,用了一点技巧。我看了代码后发现作者的技巧就是利用floor函数来完成了ceil函数的功能,而且为了防止k多加了个1,还减去了1e-9,似乎即使不减数也应该不会多加1的,毕竟运算过程中开了根号,结果应该总是小的,不过作者懒得考虑了,为了保险(作者承认)就减了。而实际上把那行代码写成这样更加方便:
int k = (int)ceil(((sqrt(8.0*n+1)-1)/2));
7. 50页的3-4计算器不知道各位怎么写的,但最简单的读取输入的方式莫过于:
scanf("%d %c%d", &a, &sign, &b);
注意%c前面的空格是必不可少的,若是不知道为什么,请参考一本较好的C语言教程。
9. 101页的一些程序上的小技巧是什么呢?就是这个(已通过作者验证):
for (int i = 0; i < D-1; i++) {
k = 2*k+(!(I%2)); // 当I是偶数的时候才往右走(k=2*k+1)
I = (I+1)/2; // 容易证明,对于除1以外的正整数来说,相邻的偶数和奇数加1除以2的结果都是一样的,所以在这里可以通用
}
10. 7.2.2中最开始的那个程序,其实还要把7.2.1的for (i = 1; i <= n; ++i)进行修改才能得到,当然在下面的代码中已经有所体现。