C陷阱与缺陷:第七,八章
第七章 可移植性缺陷
1. 标准的变更
新标准的特性能给程序带来巨大的方便,但代价是使程序失去了一部分潜在的用户。我们不能只看到当前的需要,而忽视未来可能的需要。至于是要增加程序的可移植性还是选择新标准带来的编程收益,我们需要下定决心才能做出选择,而且必须慎重对待。
2. 标识符名称的限制
ANSI C标准所能保证的只是,C实现必须能够区别出前6个字符不同的外部名称。而且,这个定义中没有区分大写字母与其对应的小写字母。
求解: 1). C语言不是区分大小写吗?为什么说没有区分大写字母与其对应的小写字母?
2). 编译环境不区分外部名称大小写的C语言实现。区分大小写不是语言本身定义的吗?和编译器的关系大吗?
3). 书中说print_fields与print_float的名称方式不恰当,并没有说不可以,是有什么副作用吗?
3. 整数大小
1). short能被int容纳, int能被long容纳
2). int类型够容纳任何的数组下标
3). 字符长度由硬件特性决定
为增加可移植性,最好将变量声明为long类型,但通常会用typedef定义一个“新的类”:
typedef long tenmil;
4. 移位运算符
1). 向右移位时,如果被移位的对象是无符号数,空出的位被0填充;如果被移位的对象是有符号数,那么可以用0填充,也可以用符号位的副本填充。
2). 被移位的对象长度是n位,那么移位的计数必须大小或等于0,且小于n。因此,不可能单次操作将所有的位都移出。
5. NULL指针
除非是用于赋值或是比较运算,出于其他任何目的使用NULL指针都是非法的。
char *p;
p = NULL;
printf(“%d”, *p); // 非法
6. 大小写的转换
在使用tolower或是toupper函数时,如果输入的信息不是字母或是大小写不对,那么得到的就是垃圾信息。所以一般先做个判断:
putchar (isupper (c) ? tolower (c) : c);
第八章 建议
1. 最重要的规避技术是:知道自己在做什么。
2. 使用圆括号或者其他方式让你的意图尽可能清楚明了。
3. 考查最简单特例和使用不对称边界。
4. 对细节处的考虑欠周的函数库实现,应预先采措某些防备的措施。
小结:《C陷阱与缺陷》大致讲到有关语法,语义,函数,预处理器和可移植性容易出现错误的几方面。不过,书中的一些所谓的“陷阱或缺陷”在今天的编译器看来,都可以捕获或是已得到改善。这是确实算得上是一本好书,书中有几处地方还未看明白。如:第五章的更改顺序文件和使用errno检测错误都没理解,第七章的标识符名的限制。应该还要翻上几遍。