在C编程中,为什么字符a=-1不同于无符号字符b=-1
我在下面写了一个小程序在C编程中,为什么字符a=-1不同于无符号字符b=-1,c,C,我在下面写了一个小程序 #include <stdio.h> main(){ char a=-1; unsigned char b=-1; printf("%d %d\n",a,b); printf("%x %x\n",a,b); if(a==b) printf("equal\n"); else printf("not equal\n"); } 因为char只有一个字节,-1以2的补码形式表示,所以我认为0xff将同时存储在a和b中,
#include <stdio.h>
main(){
char a=-1;
unsigned char b=-1;
printf("%d %d\n",a,b);
printf("%x %x\n",a,b);
if(a==b) printf("equal\n");
else printf("not equal\n");
}
因为char只有一个字节,-1以2的补码形式表示,所以我认为0xff将同时存储在a和b中,因此两者应该相等。有人能告诉我为什么它们不同,为什么a的十六进制代表是0xFFFFFF&而不是0xff。我得到了一个相关链接,但我无法得到答案。任何帮助都将不胜感激。谢谢。字符
类型有点反常,因为它与有符号字符
或无符号字符
不同(与其他整数类型不同-短
,int
,长
等,除非明确声明无符号
,否则都是隐式签名的)。char
是否实际签名取决于实现,有些编译器甚至允许您通过命令行开关指定签名
底线:永远不要假设char
是有符号的或无符号的-如果您确实需要有符号或无符号的8位数量,那么显式地使用signed char
或unsigned char
,或者更好,使用int8\u t
或uint8\u t
来自
的char
类型有点反常,因为它与有符号字符
或无符号字符
(与其他整数类型不同,short
、int
、long
等,除非明确声明unsigned
,否则这些整数类型都是隐式签名的。)字符是否实际签名取决于实现,一些编译器甚至允许您通过命令行开关指定签名
底线:永远不要假设char
是有符号的或无符号的-如果您实际需要有符号或无符号的8位数量,那么明确地使用signed char
或unsigned char
,或者更好地使用int8_t
或uint8_t
,它们是相同的。或者更确切地说,它们的基本属性是相同的表示形式相同(假设编译器使用两个补码形式)
另一方面,它们表示的值是-1和255
当您打印它们时,它们会扩展到数据类型int
,无符号字符
是零扩展,而有符号字符是符号扩展,这就解释了您看到的差异
比较这两个值时会出现相同的扩展。a==b
不比较底层表示,而是将这两个值扩展到int
,因此将255与-1进行比较,后者不相等
请注意,普通的字符可以是有符号的,也可以是无符号的。在您的环境中,它显然是有符号的。它们是相同的。或者更确切地说,它们的基本表示形式是相同的(假设您的编译器使用两个补码形式)
另一方面,它们表示的值是-1和255
当您打印它们时,它们会扩展到数据类型int
,无符号字符
是零扩展,而有符号字符是符号扩展,这就解释了您看到的差异
比较这两个值时会出现相同的扩展。a==b
不比较底层表示,而是将这两个值扩展到int
,因此将255与-1进行比较,后者不相等
请注意,普通的char
可以是有符号的,也可以是无符号的。在您的环境中,它显然是有符号的。asigned int
是有符号的,aunsigned int
是无符号的。如果您只使用int
,它意味着signed int
。对于short
、long
或long。但是char
不是这样。signed char
是有符号的,unsigned char
是无符号的,但是char
可以是有符号的,也可以是无符号的。数据类型char应该包含一个“字符”,因此它的名称是有符号的,所以它不是“真的”一种整数类型,用于保存要在计算中使用的整数。当然,字符实际上是某种类型的整数,但其类型取决于实现(C标准不强制任何特定类型)。因此,如果要将字符类型用于整数值(也用于计算),始终显式使用signed char
或unsigned char
,并且仅在您真正处理字符时使用char
,或者如果char是有符号或无符号的,则对代码完全没有影响时使用
比较失败,因为您的实现将char
定义为事实上的signed char
,因此您在最后的if
语句中将signed char
与unsigned char
进行比较。每当您比较两个不同类型的整数时,编译器都会将两个值转换为同一类型在实际执行比较之前。在您的例子中,这意味着C编译器实际执行以下操作:
if((int)a==(int)b) printf("equal\n");
else printf("not equal\n");
}
现在,这两个值不匹配的原因应该很明显了。(int)a
的值为-1
,而(int)b
的值为255
,这两个值不相等
根据类型提升的规则,char
(在您的案例中是有符号的)被提升为int
,无符号char
也被提升为int
。ISO C 2011标准规定:
如果int可以表示原始类型的所有值(受限
根据宽度(对于位字段),将值转换为int;
否则,它将转换为无符号整数
整数促销。)所有其他类型均不受整数的影响
晋升
整数值包括符号。如前所述
之前,是否为“普通”字符
if((int)a==(int)b) printf("equal\n");
else printf("not equal\n");
}