(1) 问:如果我给一个int整形赋值0xFFFF,我得到一个信息"arithmetic overflow in constant expression"(常数表达式里算术溢出)。为什么编译器不是把它当做-1呢?
答:作为一个int整形,这个变量值的范围只能是从-32768到32767。0xFFFF的值是等于65535,所以太大了。如果你确实不想使用有符号的值,可以使用unsigned int,或者直接使用-1或者~0。
一般来说,如果你想要一个所有位都为1的值,并且你不想指定它总共有多少位的话,使用~0是个好的选择,例如:
OnLimit = ~0;
它将分配一个所有位都为1的值给这个变量,对于16位的int,这个值是0xFFFF(或-1)。
下面这个宏
#define ALL_BITS_SET (~0)
也可以很有用处。
(2)问:下面这些定义
#define XTAL 8000000
#define BEEP_FREQ 3200
#define BEEP_TIME XTAL/(64*BEEP_FREQ)-1 // = 38.0625
当我把BEEP_TIME赋给一个unsigned char时,上面这些也会给我"arithmetic overflow"的信息,而这个表达式计算的结果肯定是符合unsigned char的大小的。这究竟是怎么回事?
答:你需要确保在整个算术表达式里都是使用long型计算的。8000000是会自动地变成long型数据,但是3200和64并不是,所以64*3200是被编译器评估为int型的长度,于是就发生算术溢出。使用一个'L'后缀可以强制为long型计算,例如:
#define BEEP_TIME XTAL/(64L*BEEP_FREQ)-1 // = 38.0625
注意这个'L'是附在64上——这使得它变成一个long型数据,然后64L*3200被评估下来就会按照32位长度来计算。
全部0条评论
快来发表一下你的评论吧 !