在vs2008环境下,如下代码显示不同的结果:
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main(void)
{
int d = -1;
if(d <TOTAL_ELEMENTS-2)
printf("success/n");
else
printf("failed/n");
return 0;
}
结果显示failed,而将if(d <TOTAL_ELEMENTS-2)改成if(d <(int)TOTAL_ELEMENTS-2),结果显示的是success。
C专家编程对此分析的原因是:TOTAL_ELEMENTS所定义的值是unsigned int 类型(因为sizeof()的返回类型是无符号数)。if语句在signed int和unsigned int之间测试相等性,所以d被升级为unsigned int类型,-1转换成unsigned int的结果将是一个非常巨大的正整数,致使表达式的值为假。要修正这个问题,只有对TOTAL_ELEMENTS进行强制类型转换即可。
启发:一、尽量不要再你的代码中使用无符号类型,以免增加不必要的复杂性。
二、尽量使用像int那样的有符号类型,这样在涉及升级混合类型的复杂细节时,不必担心边界情况(如-1被翻译为非常大的数)。
三、只有在使用位段和二进制掩码时,才可以用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或无符号数,这样就不必由编译器来选择结果的类型了。