1.字符是有符号数还是无符号数
在将char转换为int时,有些编译器对其进行有符号数的处理,还有一些编译器则做无符号数的处理,如果我们只想让编译器填0,而不想做有符号数符号的扩展,那么可以先把char转换为unsigned char,然后再赋给int,错误的做法是(unsigned)c,那么在将c转换为无符号整数时,c首先被转换为int,而此时可能得到非预期的结果。
2.移位运算符
对于非负整数,可以使用移位代替除法,提高程序效率,而对于有符号整数来说,即使将符号位复制到空出的位中,有符号整数的向右移位运算也并不等同于除以2的某次幂。
3.内存位置0
对于一些机器,会禁止对内存地址0的读取,而另一些则比较宽,对于这些机器,错误的使用null指针将可能造成灾难。
4.除法运算发生的截断
q=a/b;
r=a%b;
对于一个除法运算,我们希望满足下面三条:
1)q*b+r=a
2)a与q的符号相同
3)当b>0时,我们希望0<=r
而这三条一般是不会同时满足的,必须放弃至少一条,大多数程序设计语言放弃了第三条,而改为要求余数与被除数的符号相同。而有一些也可能没有这个要求,所以在遇到相关的运算时,一定要注意检查这些边界条件,对所有可能的情况作出处理,以免犯错。
5.可移植性的一个例子
if(n<0)
n=-n;
这个程序表面上看没什么问题,但是对于2的补码的机器,是可能发生溢出的(1的补码:二进制表示的下限为-(2^N-1),2的补码,二进制表示的下限-2^N),比如对于一个8位的整数-128的相反数就是溢出的(上限是127)
上面的语句是一个程序的一部分,是在开始处将n取绝对值,然后下面的操作都针对正数处理,那么我们改进的方式是写一个对偶的程序,因为正数取相反数是肯定不会溢出的,那么我们在程序的开始把n都统一为负数,然后下面的操作都针对负数进行就可以啦。
练习7-1
如果一个机器char的长度为8,那么其整数长度可能是16或者32,请问原因。
因为存在着字符寻址和字寻址两种方式并存的机器,为了实现两种方式的方便转换(即可以通过移位来实现),就把整数的大小定义成了char的2^n倍。
阅读(725) | 评论(0) | 转发(0) |