一、数据溢出问题
先看代码示意:
unsigned long mid1,mid2,mid3;
mid1=6*10000;//index1
mid2=7*10000;//index2
mid="8"*10000;//index3
咋一看,这段代码似乎是对的,其实不然,如果跟踪调试一下代码就会发现:
mid1=0xea60=60000;
mid2=0x1170=4464;
mid3=0x3880=14464;
mid1是正确的,mid2和mid3是错误的!
产生错误的原因是:
编译器在编译的时候把6*10000、7*10000以及8*10000计算得来的结果存在了一个int类型的变量当中,因此在index1 index2与index3行中发生了数据溢出,导致计算错误!
解决方法:
unsigned long mid1,mid2,mid3;
mid1=6*(unsigned long)10000;//index1
mid2=7*(unsigned long)10000;//index2
mid="8"*(unsigned long)10000;//index3
以下代码是错误的!类型转换发生在数据溢出之后
unsigned long mid1,mid2,mid3;
mid1=(unsigned long)(6*10000);//index1
mid2=(unsigned long)(7*10000);//index2
mid=(unsigned long)(8*10000);//index3
1:10000,6,7,8,等常数的数据类型应该是 int 型;
2:6*10000,7*10000,8*10000 三个表达式都存在数据范围溢出的问题;
3,mid1 结果之所以能正确,是因为内存复制的原因,系统强制将 int 转换为unsigned int {内存复制的方法}
int a="0";
if(10000*6<0) { a="0xffff"; }
改正方法:
unsigned long mid1,mid2,mid3;
mid1=6ul*10000;//index1
mid2=7ul*10000;//index2
mid= 8ul*10000;//index3
void t0_inte(void)interrupt 1 using 1
{
TH0=(256*256-1000)/256;
TL0=(256*256-1000)%256;
}
这是我以前遇到的问题, 两个赋值语句也存在类似的问题;
应该改为:
TH0=(256UL*256-1000)/256;
TL0=(256UL*256-1000)%256;
由于同级算术运算遵守从左到右的顺序,所以建议将指定常量类型的ul放在左边;
51的数据类型的表达范围较小,很容易发生数据溢出,应用时一定要考虑到是否存在溢出的可能.尽量避免了