为什么在char变量中存储255会在C中给出它的值-1?
我正在读一本C书,作者提到了一篇文章:
“ if ch (a char variable) is a signed type, then storing 255 in the ch variable gives it the value -1
”。
任何人都可以详细说明吗?
假设8位char
,这实际上是实现定义的行为。 值255不能表示为带符号的8位整数。
但是,大多数实现只是存储位模式,255为0xFF
。 使用二进制补码解释,作为带符号的8位整数,即-1
的位模式。 在一个更罕见的“补充”架构中,这将是负零点或陷阱表示的位模式,具有符号和幅度,它将是-127
。
如果两个假设中的任何一个(符号和8位char
)不成立,则该值将为¹255,因为255可表示为无符号8位整数或有符号(或无符号)整数,且大于8位。
¹标准保证CHAR_BIT
至少为8,可能更大。
这不是保证行为。 引用ANSI / ISO / IEC 9899:1999§6.3.1.3(在有符号和无符号整数之间进行转换)第3条:
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
我将按位/ 2的补码解释留给其他答案,但符合标准的signed char
甚至不能保证太小而不能保持255; 他们可能工作得很好(给出值255.)
试试十进制。 假设我们只能有3位数。 所以我们的无符号范围是0 – 999。
让我们看看999是否真的可以表现为-1(签名):
42 + 999 = 1041
因为我们只能有3位数,所以我们删除最高位数(进位):
041 = 42 - 1
这是适用于任何数字基础的一般规则。
这就是两个补码的工作原理。 在这里阅读所有相关信息。
你在其他消息中有经典的解释。 我给你一个规则:
在大小为n的带符号类型中,MSB的存在设置为1,必须解释为-2 ^(n-1)。
对于这个具体问题,假设char的大小是8位长度(1个字节),255到二进制等于:
1*2^(7) + 1*2^(6) + 1*2^(5) + 1*2^(4) + 1*2^(3) + 1*2^(2) + 1*2^(1) + 1*2^(0) = 255 255 equivalent to 1 1 1 1 1 1 1 1.
对于unsigned char,你得到255,但如果你正在处理char(与signed char相同),MSB代表负数:
-1*2^(7) + 1*2^(6) + 1*2^(5) + 1*2^(4) + 1*2^(3) + 1*2^(2) + 1*2^(1) + 1*2^(0) = -1