在过去的一天里,我的代码出现了一个严重的bug。经过一些搜索,发现这个问题似乎与char值和16进制的比较有关。我的编译器是gcc 4.4.1,在Windows上运行。 我在下面的简单代码中重现了这个问题:
char c1 = 0xFF; char c2 = 0xFE;
if(c1 == 0xFF && c2 == 0xFE)
{
//do something
}
出乎意料的是,上面的代码并没有进入循环。我完全不知道为什么,真的很需要一些帮助。这太荒谬了,解决方案肯定是(像总是一样)我犯了一个我完全忽视的巨大错误。如果我用unsigned chars替换上面的代码,它就有效了,但只在某些情况下有效。我正在努力找出原因。此外,如果我将十六进制值强制转换为char进行比较,则会正确地进入循环,如下所示:
if(c1 == (char)0xFF && c2 == (char)0xFE)
{
//do something
}
这是什么意思?为什么会发生这种情况?默认情况下,原始十六进制值不会被解释为字符吗? 对于好奇的人,我在代码中第一次注意到它是将流的前两个字节与上述十六进制值及其反向进行比较来识别字节顺序标记。
非常感谢任何帮助。
(char)
类型,编译器会像它在比较操作符另一侧的char
变量时一样进行转换。或者你可以将char
类型的变量强制转换为(unsigned char)
类型。注意,转换为(unsigned)
类型并不明智;在一个int
为4字节的机器上,将-1
转换为unsigned
会生成0xFFFFFFFF而不是0xFF。另一种选择是使用一个数组char charmap [256]
,初始化charmap [i] = i;
,然后比较c1 == charmap [0xFE]
。或者你也可以直接使用unsigned char
。 - Jonathan Lefflersigned char x = 0xFF; printf("%08x\n", x); printf("%08x\n", (unsigned char)x);
。我认为@paxdiablo在他的评论中解释得正确。 - abdus_salamprintf()
的参数被转换为int
(因为在调用像printf()
这样的可变参数函数时,所有char
的变体都会被提升为int
),然后在printf()
内部,格式指示参数应被视为unsigned int
。 - Jonathan Leffler000000FF
而不是您所建议的所有FF
。我的观点是,只要您不关心原始值的符号,将有符号字符转换为无符号字符是安全的。您是否不同意? - abdus_salam(unsigned)-1
,并没有涉及到char
类型。 - Jonathan Leffler