我试图比较字符串的第一个字符和十六进制常量以确定数据的类型。但每次失败。任何人都可以解释为什么以下比较总是失败。
char charray[] = {0xAA, 0x00, 0x02};
char ch = charray[0];
if (0xAA == ch)
{
printf("Equal\n");
}
答案 0 :(得分:9)
问题在于:
char charray[] = {0xAA, 0x00, 0x02};
char类型具有实现定义的signedness,这意味着在某些系统上它将等同于signed char
。 signed char
只能存储高达0x7F的值,MSB将被视为符号位。这就是你的情况,0xAA
被转换为有符号值-86
(实现定义了它得到的值,我假设是两个补码)。
然后,该符号会保留在表达式0xAA == ch
中,因为ch
会被提升为int
类型并保留该符号。这意味着您实际上将比较0xAA == -86
,这是假的。
为了避免这样的错误,在字节级别上进行任何形式的算术时总是使用uint8_t
。
答案 1 :(得分:1)
0xAA
是一个int
字面值。您的系统上可以是char
已签名或未签名。 C标准允许。
在0xAA == ch
中,ch
被提升为int
类型,比较结果为0。
答案 2 :(得分:1)
if (0xAA == ch)
假设char
为signed char
(char
的行为signed char
或unsigned char
的实施依赖于C),char
将被提升int
表达式中的==
以及您实际比较的32位系统:
if (0xAA == 0xFFFFFFAA)
这是假的。
阻止符号扩展的一种方法是将右操作数强制转换为unsigned char
:
if (0xAA == (unsigned char) ch)
但最好的只是在声明数组时使用unsigned char
。