Char 与 unsigned char 转换为 int

Char vs unsigned char in conversion to int

我在将 int 保存到 char 数组并将其转换回来时偶然发现了这个问题。我使用位移位和逻辑或,但我的结果以最低有效位之后的所有字节为 0xFF。

我的问题是:考虑这个例子

#include <stdio.h>

int main() {
        char c1 = 0x86;
        unsigned char c2 = 0x86;
        unsigned int i1 = 0, i2 = 0;

        i1 = (unsigned int) c1;
        i2 = (unsigned int) c2;

        printf("%x-%x\n", i1, i2);
}

为什么输出是ffffff86-86?为什么 char 的所有高位都设置为 1?

我确定有一个非常简单的答案,但我想不出一个足够具体的查询来在 google 上找到它。

如果 char 有符号或无符号,它的实现定义。

如果char是有符号的,那么当promoted to an int时会符号扩展,所以负值在提升后会保持负值.

前导 1 位是负数在 two's complement 系统中的表示方式,这是处理负数的最常见方式。


如果您的编译器对 char 进行了签名(看起来是这样),那么 c1 的初始化应该会生成警告。如果没有,那么您需要启用更多警告。

char c1 = 0x86;这里c1默认类型是signed

c1 => 1000 0110
      |
      signed bit is set(1) 

When语句 i1 = (unsigned int) c1; 执行 c1 的符号位被复制到 i1 的剩余字节中作为

   i1 =>                         1000 0110
                                 |
                                 |<--this sign bit 
   1111 1111 1111 1111 1111 1111 1000 0110 
     f   f    f    f    f    f     8    6

i2 = (unsigned int) c2;这里i2c2都声明为unsigned类型所以在这种情况下sign bit不会被复制到剩余的字节所以它打印 1st byte 中的数据是 0x86