我在char数组中保存int并将其转换回来时偶然发现了这个问题。我使用了位移和逻辑,但是我的结果最后显示为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?
我确定有一个非常简单的答案,但我无法提出足够具体的查询来在谷歌上找到它。
答案 0 :(得分:3)
如果char
已签名或未签名,则会定义实现。
如果char
已签名,那么当promoted to an int
成为符号扩展时,负值将在促销后保持其负值。
前导1
位是two's complement系统中负数的表示方式,这是处理负数的最常用方法。
如果您的编译器char
已签名(似乎是),则c1
的初始化应生成警告。如果没有,则需要启用更多警告。
答案 1 :(得分:2)
char c1 = 0x86;
此处c1
默认类型为signed
c1 => 1000 0110
|
signed bit is set(1)
何时声明
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