对于char和constant,比较总是失败的

对于char和constant,比较总是失败的,c,if-statement,char,C,If Statement,Char,我试图比较字符串的第一个字符和十六进制常量来确定数据的类型。但每次都失败了。有人能解释为什么下面的比较总是失败的吗 char charray[] = {0xAA, 0x00, 0x02}; char ch = charray[0]; if (0xAA == ch) { printf("Equal\n"); } 0xAA是一个int文本char在您的系统上可以是有符号的,也可以是无符号的。C标准允许这两种情况 在0xAA==ch中,ch被提升为int类型,比较结果为0 if (0xAA

我试图比较字符串的第一个字符和十六进制常量来确定数据的类型。但每次都失败了。有人能解释为什么下面的比较总是失败的吗

char charray[] = {0xAA, 0x00, 0x02};
char ch = charray[0];
if (0xAA == ch)
{
    printf("Equal\n");
}

0xAA
是一个
int
文本
char
在您的系统上可以是有符号的,也可以是无符号的。C标准允许这两种情况

0xAA==ch
中,
ch
被提升为
int
类型,比较结果为0

if (0xAA == ch)
假设
char
signed char
char
作为
signed char
unsigned char
的行为在C中取决于实现),
char
=
表达式中提升为
int
,在32位系统中,您实际上正在比较:

if (0xAA == 0xFFFFFFAA)
这是错误的

防止符号扩展的一种方法是将右操作数强制转换为无符号字符:

if (0xAA == (unsigned char) ch)
但最好是在声明数组时使用
无符号字符。

问题在于:

char charray[] = {0xAA, 0x00, 0x02};
char类型具有实现定义的signedness,这意味着在某些系统上它将等同于
signed char
signed char
最多只能存储0x7F的值,并且MSB将被视为符号位。这就是在您的例子中发生的情况,
0xAA
被转换为一个有符号值
-86
(它得到的值是由实现定义的,我假设是两个的补码)

符号随后被保留在表达式
0xAA==ch
中,因为
ch
随后被提升为type
int
,符号被保留。这意味着您将实际比较
0xAA==-86
,这是错误的


为了避免类似的错误,在字节级执行任何形式的算术时,始终使用
uint8\u t

不,他实际上是在比较
0xAA=-86
。不一定与
0xAA==0xFFFFFFAA
相同,这取决于隐式提升在特定系统上的结果。@Lundin如果你想挑剔,他实际上是在比较
0xAA==(有符号字符)0xAA
,这甚至与转换是实现定义的不同。我的观点是:只要左操作数(int-literal)是一个
int
,那么字符将只经过整数提升(整数提升规则)并保持有符号。但是如果literal是无符号类型,则也会有平衡(通常的算术转换)右操作数也会被转换为无符号类型。在这种情况下,您实际上会得到它等于
0xfffffaau
。但在这个特定示例中不会发生这种情况。@Lundin如果左操作数是
unsigned int
,那么
ch
仍会在最终转换之前提升为
int
rsion为
无符号整数