C-为什么字符C=129将转换为-127?

C-为什么字符C=129将转换为-127?,c,variables,char,C,Variables,Char,若我们将+128赋值给char变量,那个么它将转换为-128,因为二进制等价物1000000第一位表示符号。 129的二进制等价物是10000001,它将转换成什么值 字符c=129 谢谢, 实际上有几种可能性 如果char是有符号类型,则 char c = 129; 隐式地将int值转换为char。结果是实现定义的,或者它可以发出一个实现定义的信号,但我不知道有哪种实现可以做到这一点。在大多数实现中,转换结果为-127,因为有符号类型是使用两个s-补码表示的。在无符号8位类型中,100000

若我们将+128赋值给char变量,那个么它将转换为-128,因为二进制等价物1000000第一位表示符号。 129的二进制等价物是10000001,它将转换成什么值

字符c=129

谢谢,
实际上有几种可能性

如果char是有符号类型,则

char c = 129;
隐式地将int值转换为char。结果是实现定义的,或者它可以发出一个实现定义的信号,但我不知道有哪种实现可以做到这一点。在大多数实现中,转换结果为-127,因为有符号类型是使用两个s-补码表示的。在无符号8位类型中,10000001表示值129;在有符号8位类型中,相同的位模式表示-127;转换不需要保持相同的位模式,但通常是这样

如果在某些系统上,纯字符是无符号类型,那么值129在字符的范围内,转换只产生值129

但所有这些都假设char是8位的。C标准要求CHAR_BIT字节中的位数至少为8,或者一个CHAR对象中的位数至少为8,但允许更大。您不太可能遇到CHAR_BIT>8的系统,但这在C实现中并不少见


依靠这一切,很少是一个好主意。无论您试图通过将129分配给char对象来完成什么,都很可能有一种更好、更清晰、更可移植的方法来完成。

实际上有几种可能性

如果char是有符号类型,则

char c = 129;
隐式地将int值转换为char。结果是实现定义的,或者它可以发出一个实现定义的信号,但我不知道有哪种实现可以做到这一点。在大多数实现中,转换结果为-127,因为有符号类型是使用两个s-补码表示的。在无符号8位类型中,10000001表示值129;在有符号8位类型中,相同的位模式表示-127;转换不需要保持相同的位模式,但通常是这样

如果在某些系统上,纯字符是无符号类型,那么值129在字符的范围内,转换只产生值129

但所有这些都假设char是8位的。C标准要求CHAR_BIT字节中的位数至少为8,或者一个CHAR对象中的位数至少为8,但允许更大。您不太可能遇到CHAR_BIT>8的系统,但这在C实现中并不少见


依靠这一切,很少是一个好主意。无论您试图通过将129分配给char对象来完成什么,都很可能有一种更好、更清晰、更便于携带的方法来完成。

当数字位于负域(即签名位为1)时,当实际二进制表示(即忽略签名位)时,它们假定最小值,仅处理存储数字的部件是0

例如

有符号二进制:10000000表示十进制的-128

这是有意义的,因为对于二进制表示的每一个增量,都有一个十进制数的增量,请记住-127比-128多一个。如果您只处理十进制数,而忽略任何禁止溢出行为的规则,您将看到当数字接近最大正值时,它会立即假定为最大负值,并计数到0

您可以看到的另一点是-1的二进制表示形式是11111。如果我们将其增加1,我们得到100000000,其中前导的一个被丢弃,给我们数字0

确定有符号负数的值的一种快速方法是采用二进制表示法,忽略符号位并将其添加到最大负数

例如

如果我们有10000001的二进制表示,其中无符号值是129,我们可以看到忽略符号位我们有1,我们将其添加到-128,得到的结果是-127


请注意:我忽略了一个事实,即有时不允许溢出,并且可能导致未定义的行为。在这个答案中,我也在处理签名字符。如果您处理的是无符号字符,则使用完整的二进制表达式给出它的值,例如10000001=129。

当数字位于负域,即签名位为1时,当实际二进制表示(即忽略签名位)时,它们假定最小值,仅处理存储数字的部件是0

例如

有符号二进制:10000000表示十进制的-128

这是有意义的,因为对于二进制表示的每一个增量,都有一个十进制数的增量,请记住-127比-128多一个。如果您只处理十进制,而忽略任何禁止溢出行为的规则,那么当数字接近最大值时,您将看到这一点 imum正值它立即假定为最大负值,最多可计数为0

您可以看到的另一点是-1的二进制表示形式是11111。如果我们将其增加1,我们得到100000000,其中前导的一个被丢弃,给我们数字0

确定有符号负数的值的一种快速方法是采用二进制表示法,忽略符号位并将其添加到最大负数

例如

如果我们有10000001的二进制表示,其中无符号值是129,我们可以看到忽略符号位我们有1,我们将其添加到-128,得到的结果是-127


请注意:我忽略了一个事实,即有时不允许溢出,并且可能导致未定义的行为。在这个答案中,我也在处理签名字符。如果您处理的是无符号字符,则使用完整的二进制表达式给出它的值,例如10000001=129。

负数存储为该数字正数的2的补充

例如:

  -127 is stored as 2's compliment of 127
    127 is 01111111 in binary
    2's compliment=(1's compliment of a number) + 1
    therefore, 2's compliment of 127(01111111) is 10000001(-127).

And 10000001 is 129:: Therefore when you give 129 to a char variable, compiler takes it as negative number 127.
类似地,130将被分配为-126


谢谢

负数存储为2对该数字的正数的补充

例如:

  -127 is stored as 2's compliment of 127
    127 is 01111111 in binary
    2's compliment=(1's compliment of a number) + 1
    therefore, 2's compliment of 127(01111111) is 10000001(-127).

And 10000001 is 129:: Therefore when you give 129 to a char variable, compiler takes it as negative number 127.
类似地,130将被分配为-126



谢谢

尝试在一个字符中存储+129将导致在其中存储-127。当我们试图将+128存储在一个字符中时,会存储负边的第一个数字,即-128。这是因为从+128010000000的9位二进制文件中,只存储最右边的8位。但当存储10000000时,最左边的位是1,它被视为符号位。因此,这个数字的值变成了-128,因为它实际上是二进制2的-128的补码。一般来说,如果我们超出了从正数开始的范围,那么我们最终会到达负数。反之亦然。如果我们超出了从反面开始的范围,我们将在正面结束。

尝试在一个字符中存储+129将导致在其中存储-127。当我们试图将+128存储在一个字符中时,会存储负边的第一个数字,即-128。这是因为从+128010000000的9位二进制文件中,只存储最右边的8位。但当存储10000000时,最左边的位是1,它被视为符号位。因此,这个数字的值变成了-128,因为它实际上是二进制2的-128的补码。一般来说,如果我们超出了从正数开始的范围,那么我们最终会到达负数。反之亦然。如果我们超出了从负端到正端的范围。

溢出。溢出。@Cornstalks:在这种情况下,这是一个转换,它产生一个实现定义的结果或引发一个实现定义的信号,但我不知道有任何实现会这样做。我只想知道我们是否有int I=129,我们是否有printf%c,I:将打印哪个字符?这实际上是一个不同的问题;%c需要一个int参数。我是int参数,对吗?我想知道将使用上述语句打印的字符的ASCII值。溢出。溢出。@Cornstalks:在这种情况下,这是一个转换,它产生一个实现定义的结果或引发一个实现定义的信号,但我不知道有任何实现会这样做。我只想知道我们是否有int I=129,我们是否有printf%c,I:将打印哪个字符?这实际上是一个不同的问题;%c需要一个int参数。我是int参数,对吗?我想知道将使用上述语句打印的字符的ASCII值。我只是想了解为什么在我们指定129时将-127指定给字符变量。@smaugdragon:我的答案没有解释吗?我很困惑,但现在我得到了你的解释。谢谢我只是想弄明白为什么在我们分配129时-127被分配给char变量。@smaugdragon:我的答案没有解释吗?我很困惑,但我现在得到了你的解释。谢谢