【问题标题】:Why stores 255 in a char variable give its value -1 in C?为什么在 char 变量中存储 255 在 C 中给出它的值 -1?
【发布时间】:2012-05-03 02:36:02
【问题描述】:

我在看一本C书,有一段作者提到的文字:

if ch (a char variable) is a signed type, then storing 255 in the ch variable gives it the value -1”。

谁能详细说明一下?

【问题讨论】:

  • 而您从未想过只查找签名字符的表示形式是什么?
  • @tbert:您没有阅读我对最高投票答案的评论。我开始在 c 中寻找东西,我的问题值得一票否决?
  • 在明确提供答案后您仍然感到困惑?可能。

标签: c char signed


【解决方案1】:

假设 8 位 chars,这实际上是实现定义的行为。值 255 不能表示为带符号的 8 位整数。

但是,大多数实现只是存储位模式,对于 255,位模式是 0xFF。使用二进制补码解释,作为有符号 8 位整数,即-1 的位模式。在一个罕见的补码架构上,这将是负零的位模式或带有符号和大小的陷阱表示,它将是-127

如果两个假设(有符号性和 8 位 chars)中的任何一个不成立,则该值将是¹ 255,因为 255 可以表示为无符号 8 位整数或有符号(或无符号) 8位以上的整数。

¹ 标准保证CHAR_BIT 至少为8,可能更大。

【讨论】:

  • 请注意,char 也可能是无符号位或超过 8 位,在这种情况下,实际上是 255
  • 是的。 OP 引用的文本中假设了签名,我特别提到了 8 位 chars 的额外假设。但是,我应该在答案中明确提及其他可能性。谢谢提醒。
  • 我还是迷路了。我知道 255 不能用有符号字符表示,因为有一位为符号保留。在那种情况下,为什么编译器只是像许多其他人一样给我们未定义的行为?为什么这里涉及到二进制补码? (我已经知道二进制补码是如何工作的)
【解决方案2】:

试试十进制。假设我们只能有 3 位数字。所以我们的无符号范围是 0 - 999。

让我们看看 999 是否真的可以表现为 -1(有符号):

42 + 999 = 1041

因为我们只能有 3 位,所以我们去掉了最高位(进位):

041 = 42 - 1

这是适用于任何数字基数的一般规则。

【讨论】:

  • 你的意思是 042 = 41 - 1 或 041 = 42 - 1
【解决方案3】:

这不是保证行为。引用 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 chars 甚至不能保证太小而不能容纳 255;它们可能工作得很好(给出值 255。)

【讨论】:

    【解决方案4】:

    这就是二进制补码的工作原理。阅读所有相关信息here

    【讨论】:

    • 我知道补码是如何工作的。但我在这里看不到任何关系。请您进一步解释一下吗?
    【解决方案5】:

    您在其他消息中有经典的解释。我给你一个规则:

    在大小为 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
    

    【讨论】:

      猜你喜欢
      • 2021-01-24
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      相关资源
      最近更新 更多