当Int超出char的范围时,C中的Int到char转换规则

当Int超出char的范围时,C中的Int到char转换规则,c,C,请参阅下面的C代码 #include <stdio.h> int main(void) { char c1 = 3000; char c2 = 250; printf("%d\n",c1); printf("%d\n",c2); } 请解释此处应用的整数到字符转换规则,因为3000和250都不在字符范围(-128到127)之内。整数使用4字节,字符使用1字节。C中的数字表示为有符号,这意味着左边的第一位表示符号(正数、负数),其余为全补数。所以数字

请参阅下面的C代码

#include <stdio.h>

int main(void)
{
    char c1 = 3000;
    char c2 = 250;
    printf("%d\n",c1);
    printf("%d\n",c2);
}

请解释此处应用的整数到字符转换规则,因为3000和250都不在字符范围(-128到127)之内。

整数使用4字节,字符使用1字节。C中的数字表示为有符号,这意味着左边的第一位表示符号(正数、负数),其余为全补数。所以数字
3000
用二进制表示为
00000000000000000010111000
,对于int,它是这样存储的。因为char仅为1字节,所以最后8位表示char变量中保存的数字,即
10111000
。当你把它转换成十进制时,你会得到-72

请解释此处应用的整数到字符转换规则,因为3000和250都在字符(-128到127)范围之外

首先请注意,C没有指定
char
是有符号的还是无符号的。这要由实现来决定,它们在这方面并不一致。在
char
无符号的实现中,250在其范围内

但是,假设您的
char
s是有符号的,这似乎与您的结果一致,赋值语句中隐含的转换C规则将无法满足您的要求:

新类型已签名,且无法在其中表示值;要么结果是实现定义的,要么引发实现定义的信号

()

显然没有发出信号,因此结果是实现定义的。其中一种可能性是,每个赋值的最低有效
CHAR\u位
位存储在目标变量中


当您调用
printf()
时,还有一个额外的转换。参数从
char
提升到
int
,并且由于
int
可以表示
char
类型的所有值,因此其中一个是值保留。这让我们可以得出结论,您的实现将
int
转换为
char
,方法是只保留最低有效位,并将其解释为8位2的补码。如果您试图将数字(如3000)存储为仅8位宽的值,您认为该数字会发生什么变化?提示:检查3000的十六进制或二进制表示形式,只查看较低的8位,并确定当被视为2的补码8位值时该值是什么。如果你不确定2的补码是什么,你可以用谷歌搜索它。当你的大小溢出时会发生什么?当你把一个16位(或有符号的短字符)的值塞进一个8位的无符号字符时,你认为会发生什么?谢谢。这有帮助。从形式上讲,从int到char的转换规则如下:1)int被转换成二进制,然后只考虑最后8位。2) 以2的补码形式解释二进制,这将给出结果。为什么它不是转换?假设我把字符c1=3000.5。那么3000.5是一个双倍数字,它必须转换为char类型,对吗?同样的道理,为什么我们不能把这个称为从int到char的转换呢?@chux unsigned很容易:)
int
根据标准和在一些实际实现中使用了16位。C既有有有符号的整数类型,也有无符号的整数类型,并且它不需要负数来表示二的补码(尽管在实践中,现在二的补码无处不在)。C没有指定对于
char
来说太大而无法保存的值如何转换为
char
,尽管您描述的机制确实非常常见。
-72

-6