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;
这里i2
和c2
都声明为unsigned
类型所以在这种情况下sign bit
不会被复制到剩余的字节所以它打印 1st byte
中的数据是 0x86
我在将 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;
这里i2
和c2
都声明为unsigned
类型所以在这种情况下sign bit
不会被复制到剩余的字节所以它打印 1st byte
中的数据是 0x86