当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赞美。