书上都说keil对数值常量的默认类型是int(注:keil中,sizeof(int) = 2)
这样的话,对于下面表达式是不是有溢出问题?
20000000 / (1000*12) (因为200000000远大于int所能表示的范围)
但是keil 编译出来运行结果是正确的。 为什么?
经过试验发现, keil对代码中的数值常量不总是按int处理的。 它会智能的根据数值大小进行切换。 比如 sizeof(20) = 2; sizeof(20000000) = 4;
延伸话题: 为了代码更好的可读性,对于较大的数,我们一般不直接敲入代码,怕掉0啊! 而是写成表达式,让计算机来算,比如: (20*1000*1000)。
这时问题出来了,(20*1000*1000) /(1000*12)的结果等于0。 啊?! 肯定是(20*1000*1000)溢出了。 原来是这三个数都会当成int型,而乘积结果远超出int所表示的范围,即(-65536/2, 65536/2-1).
这时,我们应该怎么办? 一般地,有两种办法1) (unsigned long)20 * 1000 * 1000 2) 20ul * 1000 * 1000。 第二种办法更常用。
总结一下, 我们写代码时,习惯性会在大数后面加ul(注,这是好习惯,有利于平台移植,也能防止溢出),但对小数参与乘法的case就不太关注溢出问题。 实际上后者遇到的问题更多。
注意,上面的论述基于Keil平台。gcc下所有数值常量 都是int型, 但其长度是4个字节,所以较少遇到溢出的问题,当然在表示大数和乘法运算也需要注意。