一些学习单片机和C语言遇到的问题

本文详细解析了数据溢出问题的成因,并通过实例展示了如何正确使用数据类型转换来避免溢出,同时提供了常见数据类型和算术运算中的溢出风险分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数据溢出问题

先看代码示意:

 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的数据类型的表达范围较小,很容易发生数据溢出,应用时一定要考虑到是否存在溢出的可能.尽量避免了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值