考虑以下计划
void main(){
char t = 179;
printf("%d ",t);
}
输出为-77。 但是179的二进制表示是
10110011
所以,不应该输出-51,考虑第1位是烧焦位。 -77的二进制表示是
11001101
似乎有点顺序颠倒了。发生了什么事?请有人建议。
答案 0 :(得分:3)
您声称-77
的二进制表示形式为11001101
,但反转是您的。 -77
的二进制表示形式为10110011
。
二进制10110011
无符号是十进制179
。
二进制10110011
已签名为十进制-77
。
您已将超出范围的值179
分配给signed char
。它理论上可能是未定义的行为,但除了抛出错误之外,在signed char
中放置除了8位值之外的任何东西都是非常差的编译器。
但是在打印时,它被解释为负数,因为b7已设置。
答案 1 :(得分:2)
看起来char
是您系统上的签名类型。 char
的有效范围为[-128,127]
使用
char t = 179;
编译器使用179的补码(最有可能是-77)并将该值赋给t
。
答案 2 :(得分:1)
要在2的补码中转换正数和负数,请反转所有位,然后加1。
10110011
01001100(反转所有位)
01001101(加1)
那是77十进制
答案 3 :(得分:0)
Char可以是签名或未签名的:这取决于您的编译器。
如果签名,则可以是2s或1补充。
此外,它可能大于8位,尽管sizeof char定义为1。
因此,不建议依赖特定的代表。
答案 4 :(得分:0)
请注意,许多系统char
都已签名。因此,当您将179(类型为int
)分配给char
时,此值超出char
范围,因此它是未指定的行为。
6.3.1.3有符号和无符号整数:
当具有整数类型的值转换为除_Bool之外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。否则,如果新类型是无符号的,则通过重复地添加或减去一个无符号整数来转换该值,该无符号整数可以是新类型中可以表示的最大值,直到该值在新转换为类型的范围内。 否则,新类型已签名且值无法在其中表示;结果是实现定义的,或者引发实现定义的信号。
如果您将类型更改为unsigned char
,您的程序将正确执行。
另请注意,char
,signed char
和unsigned char
是3种不同的类型,与int
和signed int
不同。 char
的签名是实现定义。