【C语言笔记】【陷阱系列】 有符号变量与常数比较问题
陷阱系列内容。用于记录各式各样有陷阱的C语言情况☺。
陷阱代码
首先我们看下如下代码,这个代码的打印结果是什么?
int main(int argc, char* argv[])
{
char value = 0x80;
if(value == 0x80)
printf("value == 0x80\n");
else
printf("value != 0x80\n");
return 0;
}
代码运行后的结果:
value != 0x80
居然value的值与0x80是不相等的,这是为什么呢?
说明
在进行比较if(value == 0x80)
时,用于比较的数0x80是十六进制整形常量(Integer Literals),而十六进制整形常量可能的类型是int,unsigned int,long,unsigned long,在默认情况下,常量的类型就是上述类型中长度最短并且可以容纳整个数值的类型。
所以在这里,0x80的类型就是int,假设使用的平台int是32位的,那么这个0x80就是0x00000080。然后value
的类型是char,在进行比较时,类型得相同,要先进行类型转换,由char转换为int,由于char是有符号类型,所以高位都会补1,假设使用的平台int是32位的,那么数值就是0xffffff80。
在进行比较的时候,就成了if(0xffffff80 == 0x00000080)
,明显是不相等的,导致最后运行的结果为value != 0x80
。
同理,将代码中value的类型变成short,对比的数值换成0x8000,也会造成该问题:
int main(int argc, char* argv[])
{
short value2 = 0x8000;
if(value2 == 0x8000)
printf("value2 == 0x8000\n");
else
printf("value2 != 0x8000\n");
return 0;
}
代码运行后的结果:
value2 != 0x8000
只有当类型为int的时候,才是正确的:
int main(int argc, char* argv[])
{
int value3 = 0x80000000;
if(value3 == 0x80000000)
printf("value3 == 0x80000000\n");
else
printf("value3 != 0x80000000\n");
return 0;
}
代码运行后的结果:
value3 == 0x80000000
因此在使用有符号变量数值与常量进行对比时,需要注意该陷阱。
[参考资料]
C和指针
本文链接:https://blog.csdn.net/u012028275/article/details/120146226