当int超出char范围时,C中的Int到char转换规则
请参阅以下C代码。
#include int main(void) { char c1 = 3000; char c2 = 250; printf("%d\n",c1); printf("%d\n",c2); }
上面代码的输出是
-72 -6
请解释此处应用的整数到字符转换规则,因为3000和250都在char范围之外(-128到127)。
请解释此处应用的整数到字符转换规则,因为3000和250都在char范围之外(-128到127)。
首先请注意,C不指定char
是有符号还是无符号。 这是由实施来决定的,而且它们并不一致。 在char
未签名的实现上,250在其范围内。
但是,假设您的 char
已签名,这确实与您的结果一致,则赋值语句中隐含的转换的C规则将不会满足您:
新类型已签名,其值无法表示; 结果是实现定义的,或者引发实现定义的信号。
( C2011 6.3.1.3/3 )
显然没有发出信号,因此结果是实现定义的。 其中的可能性是每个指定值的最不重要的CHAR_BIT
位存储在目标变量中。
调用printf()
时会有一个额外的转换。 参数从char
提升为int
,因为int
可以表示char
类型的所有值,因此该值是保值的。 这使我们得出结论,您的实现通过仅保留最低有效位并将它们解释为8位二进制补码来实现将int
转换为char
确实是合理的。
整数使用4个字节,char使用1个字节。 C中的数字表示为带符号,表示左边的第一位表示符号(正数,负数),其余数字表示满数字。 因此,数字3000
表示二进制的00000000000000000000000010111000
,对于int,它就像这样存储。 因为char只有1个字节,所以最后8位表示char变量中保存的数字,即10111000
。 当你将它转换为十进制时,你将有-72。
因此,当您从int
(32位长)转换为char
(8位长)时,您基本上会丢弃除最右边的8位之外的所有内容。 所以:
二进制3000
是:
00000000000000000000101110111000
删除24个最高有效位(在这种情况下,从左到右为24位, 000000000000000000001011
)。 你得到
10111000
注意1
在前面它代表负数-
(记住这个以后),翻转这些位然后你得到
01000111
并添加1,你得到:
01001000
这是64+8 = 72
,现在从上面添加负号,你得到-72
。 这将教你如何将char
转换为int
以及如何将负数从二进制转换为十进制
让我们做250没有太多解释:
250
是:
00000000000000000000000011111010
从左侧丢弃所有16 0
s你得到:
11111010 // negative
翻动
00000101
加1
00000110
这等于6
附加负号,你得到-6
我的建议是学习2s赞美。