比较字符与十六进制值
最后一天,我的代码中出现了一个令人讨厌的错误,经过一番搜索后,该错误似乎与字符值和十六进制之间的比较有关。我的编译器是在 Windows 上运行的 gcc 4.4.1。 我在下面的简单代码中复制了这个问题:
char c1 = 0xFF; char c2 = 0xFE;
if(c1 == 0xFF && c2 == 0xFE)
{
//do something
}
令人惊讶的是上面的代码没有进入循环。我完全不知道为什么,并且非常感谢对此的帮助。这太荒谬了,解决方案一定是(一如既往)我完全忽视的一个巨大错误。
如果我用无符号字符替换上面的内容,它就可以工作,但仅在某些情况下有效。我正在努力找出发生了什么事。此外,如果我将十六进制值转换为 char ,相比之下它会正确进入循环,如下所示:
if(c1 == (char)0xFF && c2 == (char)0xFE)
{
//do something
}
这是什么意思?为什么会发生这种事?默认情况下,原始十六进制值是否解释为字符? 出于好奇,我在代码中第一次注意到它是将流的前 2 个字节与上述十六进制值及其相反的字节顺序标记进行比较。
任何帮助表示赞赏
For the last day I have had a nasty bug in my code which after some searching appears to be related to comparison between char values and hex. My compiler is gcc 4.4.1 running on Windows.
I replicated the problem in the simple code below:
char c1 = 0xFF; char c2 = 0xFE;
if(c1 == 0xFF && c2 == 0xFE)
{
//do something
}
Surprisingly the code above does not get in the loop. I have absolutely no idea why and would really appreciate some help on this. It is so absurd that the solution must be (as always) a huge mistake on my part that I totally overlooked.
If I replace the above with unsigned chars it works, but only in some cases. I am struggling to find out what's going on. In addition if I cast the hex values to char in comparison it enters the loop correctly like so:
if(c1 == (char)0xFF && c2 == (char)0xFE)
{
//do something
}
What does that mean? Why can it be happening? Isn't the raw hex value interpreted as a char by default?
For the curious the point in my code where I first noticed it is comparison of first 2 bytes of a stream with the above hex value and their reverse to idenity the Byte Order Mark.
Any help is appreciated
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
普通
char
可以是有符号
或无符号
。如果类型是unsigned
,那么一切都会按您的预期工作。如果类型是
signed
,则将0xFF分配给c1
意味着执行比较时该值将提升为-1
,但是0xFF 是常规正整数,因此-1 == 0xFF
比较失败。请注意,
char
、signed char
和unsigned char
类型是不同的,但其中两个具有相同的表示形式(两者之一是字符
)。Plain
char
can besigned
orunsigned
. If the type isunsigned
, then all works as you'd expect.If the type is
signed
, then assigning 0xFF toc1
means that the value will be promoted to-1
when the comparison is executed, but the 0xFF is a regular positive integer, so the comparison of-1 == 0xFF
fails.Note that the types
char
,signed char
andunsigned char
are distinct, but two of them have the same representation (and one of the two ischar
).将字符与十六进制进行比较时,必须小心:
使用 == 运算符将 char 与 0x80 进行比较总是会导致 false?
我建议 C99 中引入这种语法,以确保
避免强制转换,这是不必要的并且类型不安全。
它告诉编译器 0xFF 是一个 char 而不是 int,这将解决您的问题。
clang 编译器也会警告您:
常量 128 与类型 'char' 的表达式的比较始终为 false [-Werror,-Wtautological-constant-out-of-range-compare]
When comparing char to hex you must be careful:
Using the == operator to compare a char to 0x80 always results in false?
I would recommend this syntax introduced in C99 to be sure
Avoid the cast, it's unnecessary and isn't type safe.
It tells the compiler that the 0xFF is a char rather than an int, this will solve your issue.
clang compiler will warn you about this also:
comparison of constant 128 with expression of type 'char' is always false [-Werror,-Wtautological-constant-out-of-range-compare]
文字
0xff
不是char
,而是int
(有符号)。当您将其硬塞到 char 变量中时,它会很好地适合,但是根据您的 char 类型是有符号还是无符号,这将影响它在表达式中的升级方式(请参阅以下)。在像
if (c1 == 0xff)
这样的表达式中,c1
变量将被提升为整数,因为0xff
就是这样。 它的升级内容取决于它是否已签名。最重要的是,您可以做两件事之一。
确保您使用
signed char
,以便它“符号扩展”为正确的int
。我的意思是一个无符号的 char0xff
将变成(对于 4 字节int
)0x000000ff
(所以它仍然是 255),但是一个有符号的字符将变为0xffffffff
(因此它仍然是 -1)。将文字调整为与变量相同的类型,您已经使用
(char)oxff
执行此操作。The literal
0xff
is not achar
, it's aint
(signed). When you shoehorn that into achar
variable, it will fit okay but, depending on whether yourchar
type is signed or unsigned, this will affect how it's upgraded in expressions (see below).In an expression like
if (c1 == 0xff)
, thec1
variable will be promoted to an integer since that's what0xff
is. And what it's promoted to depends on whether it's signed or not.Bottom line, you can do one of two things.
Ensure that you use
signed char
so that it "sign-extends" to the correctint
. By that I mean an unsigned char0xff
would become (for a 4-byteint
)0x000000ff
(so it's still 255) but a signed one would become0xffffffff
(so it's still -1).Shoehorn the literal into the same type as the variable, which you're already doing with
(char)oxff
.字符 0xFE 将被转换为负整数。表达式中的常量将被转换为正整数。
The character 0xFE will he translated into a negative integer. The constants in the expression will be translated into positive integers.
我通过将变量转换为 UINT16(针对我的编译器进行了优化)解决了这个问题。在您的情况下,您会将 c1 和 c2 转换为 INT
I solved it by casting my variables to UINT16 (optimized for my compiler). In your case, you would be casting c1 and c2 as INT