#include "stdio.h"
int array[] = {1,2,3,4,5,6};
#define TOTAL_ELEM sizeof(array)/sizeof(array[0])
int main(int argc, char* argv[]) {
int d = -1;
printf("total_elem = %d\n",TOTAL_ELEM);
if (d <= TOTAL_ELEM)
printf("samll\n");
else printf("large\n");
return 0;
}
|
上述代码,我们理所当然的认为应该输出small,但是程序实际的运行结果确实输出了large。这个诡异的问题是因为C语言重的类型转换的问题引起的。
TOTAL_ELEM所定义的值是unsigend int类型(因为sizeof()的返回值是unsigned int类型)。if语句在signed int和unsigned int类型之间作比较,会自动的将signed int提升为unsigned int类型,而-1转换为无符号整形是个很大很大的数,所以就出现了上面的诡异的BUG。
采用通俗的语言来描述ANSI C标准所定义的类型提升如下所述:
当执行算数运算的时候,操作数的类型不同,就会发生转换,数据类型一般朝着浮点精度更高,长度更长的方向转换,整形数如果转换为signed不会丢失信息,就转换为signed,否则转换为unsigned。
所以在《C专家编程》重,作者对于我们使用无符号类型的建议是
1、尽量不要在代码中使用无符号类型,以避免增加不必要的复杂性。尤其是,不要仅仅因为无符号数不存在负数,而使用它表示数量
2、尽量使用像int那样的有符号类型,这样涉及升级混合类型的复杂细节时,不必要担心边界情况(如-1被翻译成很大的正数)。
3、只有在使用位段和二进制掩码的时候,才可以使用无符号数。应该在表达式中使用强制类型转换,是操作数均为有符号数或者无符号数,这样就不必由编译器来选择结果。
阅读(1440) | 评论(0) | 转发(0) |