对于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
随后被提升为typeint
,符号被保留。这意味着您将实际比较0xAA==-86
,这是错误的
为了避免类似的错误,在字节级执行任何形式的算术时,始终使用uint8\u t
。不,他实际上是在比较0xAA=-86
。不一定与0xAA==0xFFFFFFAA
相同,这取决于隐式提升在特定系统上的结果。@Lundin如果你想挑剔,他实际上是在比较0xAA==(有符号字符)0xAA
,这甚至与转换是实现定义的不同。我的观点是:只要左操作数(int-literal)是一个int
,那么字符将只经过整数提升(整数提升规则)并保持有符号。但是如果literal是无符号类型,则也会有平衡(通常的算术转换)右操作数也会被转换为无符号类型。在这种情况下,您实际上会得到它等于0xfffffaau
。但在这个特定示例中不会发生这种情况。@Lundin如果左操作数是unsigned int
,那么ch
仍会在最终转换之前提升为int
rsion为无符号整数
。