如何解释这一点,当我们将带符号的char转换为int / hex时会发生什么?

问题描述

|
signed char num = 220; //DC in hex
printf(\"%02X\\n\",num);
printf(\"%d\\n\",num);
我知道
signed char
只能表示
-128~127
,但是为什么上面的输出是:
FFFFFFDC
-36
什么原因? 更新 我上面的代码仅是针对我的问题,即
what happens when we cast signed char to int/hex
    

解决方法

        作为起点,十六进制为220 = DC,二进制为11011100。 第一位是符号位,剩下1011100。如果补码(得到0100011),则取每个2的补码,然后加一个,得到0100100-这是36。 当将已签名的字符转换为已签名的int时,它不会说“如果未签名则为220”,而是“这是-36,使其为-36的int”,对于32位二进制补码表示为FFFFFFDC,因为它必须是int整个大小的负值(这称为符号扩展):
+36 as a 32-bit value: 00000000000000000000000000100100
complement:            11111111111111111111111111011011
add one:               11111111111111111111111111011100
或者,以十六进制
FFFFFFDC
。 这就是为什么您必须小心
printf(\"%x\",ch);
(和亲戚)的原因-如果您打算只获取两位数字的值,并且对字符进行签名,则可能会得到8位数字。如果需要将其取消签名,请始终指定\“ unsigned char \”。     ,        正如您所指出的,签名的汽车的最大值可以为127。但是,负数的原因是char的存储方式。所有带符号的整数类型都将最后一位保存为符号,0/1表示正/负。但是,编译器不会检查溢出,因此当您尝试将num分配给220时,它会将值溢出到符号位中,因为它无法将其放入char的前7位(chars为1字节)。结果,当您尝试读取内存中的内容时,它会看到抛出的符号位,从而使编译器认为,与其看到的是预期的大正数,不如看到的是负的小值。因此,您看到的输出。 编辑 回应您更新的问题。发生的一切是,编译器将复制或扩展char以使其具有4个字节的内存,解释char的值,然后将其重写到新的int的内存中。在这种情况下,程序在运行时会认为char的值是-36而不是220,因为它在转换之前将这些位解释为带符号的char。然后,当它强制转换时,它只创建一个值为-36的int值。     ,        您在赋值上的溢出,以及当您将其提升为int以十六进制形式查看时,加上了符号扩展名...请参阅在将无符号字符转换为整数类型的背景下发生了什么?     ,        通过\“ ... \”传递时,任何小于\“ int \”的类型都将转换为\“ int \”。这意味着您的负字符转换为负int,而FFF以十六进制打印输出显示。