我在看一本C书,有一段作者提到的文字:
“ if ch (a char variable) is a signed type, then storing 255 in the ch variable gives it the value -1
”。
任何人都可以详细说明吗?
假设 8-bit char
s,这实际上是实现定义的行为。值 255 不能表示为带符号的 8 位整数。
但是,大多数实现只是存储位模式,对于 255 是0xFF
. 使用二进制补码解释,作为有符号 8 位整数,即-1
. 在一个罕见的补码架构上,这将是负零的位模式或陷阱表示,具有符号和大小,它将是-127
.
如果两个假设(有符号和 8 位char
s)中的任何一个不成立,则该值将是¹ 255,因为 255 可表示为无符号 8 位整数或超过 8 位的有符号(或无符号)整数.
¹ 标准保证CHAR_BIT
至少为 8,它可能更大。
用十进制试试。假设我们只能有 3 位数字。所以我们的无符号范围是 0 - 999。
让我们看看 999 是否真的可以表现为 -1(有符号):
42 + 999 = 1041
因为我们只能有 3 位数字,所以我们去掉了最高位(进位):
041 = 42 - 1
这是适用于任何数基的一般规则。
这就是二进制补码的工作原理。在这里阅读所有相关信息。
这不是保证的行为。引用 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
s 甚至不能保证太小而不能容纳 255;他们可能工作得很好(给出值 255。)
您在其他消息中有经典解释。我给你一个规则:
在大小为 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