有符号和无符号数据类型之间的区别?

时间:2021-11-12 23:28:20
main()
{
    char i=255;
    printf("\n%x\n",i);
}

output:ffffffff

输出:FFFFFFFF

main()
{
    u_char i=255;
    printf("\n%x\n",i);
}

output:ff

输出:FF

What is happening here? Kindly explain the output to me with some good links. This is a very basic thing I guess and I am getting really confused...

这里发生了什么?请通过一些好的链接向我解释输出。这是我猜的一个非常基本的事情,我真的很困惑......

4 个解决方案

#1


10  

What you are seeing here is caused by two things:

你在这里看到的是两件事:

  • 255 does not fit in the range of char (note that it is implementation-defined whether char is equivalent to signed char or unsigned char, but evidently on your platform it is signed char). The resulting behaviour is implementation-defined, but typically it will wrap round and become -1; see two's complement.
  • 255不适合char的范围(请注意,它是实现定义的,无论char是等效于signed char还是unsigned char,但显然在您的平台上它是signed char)。结果行为是实现定义的,但通常它将换行并变为-1;看两个补码。
  • integer promotion, because printf() is a variable-argument function. Integral-type arguments (like char) are automatically promoted to int.
  • 整数提升,因为printf()是一个变量参数函数。积分类型参数(如char)会自动提升为int。

So printf() sees an int with a value of -1, and prints its hexadecimal representation accordingly.

因此printf()看到一个值为-1的int,并相应地打印其十六进制表示。

For the unsigned case, there is no wrap-around. printf() sees an int with a value of 255, and prints its hexadecimal representation accordingly (omitting the leading zeros).

对于未签名的情况,没有环绕。 printf()看到一个值为255的int,并相应地打印其十六进制表示(省略前导零)。

#2


4  

The C compiler has to expand the value passed to printf (this is called "promotion"), because printf is a variadic function (it can be called with differing arguments). For values of type char, the promoted value is of type int. Since your compiler's char type seems to be signed, the promoted value is sign extended. In binary:

C编译器必须扩展传递给printf的值(这称为“提升”),因为printf是一个可变参数函数(可以使用不同的参数调用它)。对于char类型的值,提升的值为int类型。由于您的编译器的char类型似乎已签名,因此提升的值是符号扩展的。二进制:

char i = 255           // or: 11111111 in binary
int promoted_i = -1    // or: 11....11111 (usually, 32 or 64 ones)

In the unsigned case, no sign-extension happens:

在未签名的情况下,不会发生符号扩展:

char u = 255           // or: 11111111 in binary, same as above but with different interpretation
unsigned int pu = i    // or: 00....0011111111 (8 ones, preceded by the appropriate number of zeroes) 

#3


0  

char i = 255; invokes implementation-defined behavior by converting a value to a signed type into which it does not fit (assuming char is only 8 bits and plain char is signed, both of which are also implementation-specific.

char i = 255;通过将值转换为不适合的有符号类型来调用实现定义的行为(假设char只有8位且plain char已签名,两者都是特定于实现的。

#4


0  

When you set an 8-bit signed variable to the value 255, which it can't hold, it seems in this case it sets the negative (high-end) flag to 1, so the value would be -1 if it were signed, but then it gets converted to an integer -1 which is ffffffff.

当你将一个8位有符号变量设置为它不能容纳的值255时,在这种情况下它似乎将负(高端)标志设置为1,因此如果它被签名则该值为-1 ,然后它被转换为整数-1,即ffffffff。

#1


10  

What you are seeing here is caused by two things:

你在这里看到的是两件事:

  • 255 does not fit in the range of char (note that it is implementation-defined whether char is equivalent to signed char or unsigned char, but evidently on your platform it is signed char). The resulting behaviour is implementation-defined, but typically it will wrap round and become -1; see two's complement.
  • 255不适合char的范围(请注意,它是实现定义的,无论char是等效于signed char还是unsigned char,但显然在您的平台上它是signed char)。结果行为是实现定义的,但通常它将换行并变为-1;看两个补码。
  • integer promotion, because printf() is a variable-argument function. Integral-type arguments (like char) are automatically promoted to int.
  • 整数提升,因为printf()是一个变量参数函数。积分类型参数(如char)会自动提升为int。

So printf() sees an int with a value of -1, and prints its hexadecimal representation accordingly.

因此printf()看到一个值为-1的int,并相应地打印其十六进制表示。

For the unsigned case, there is no wrap-around. printf() sees an int with a value of 255, and prints its hexadecimal representation accordingly (omitting the leading zeros).

对于未签名的情况,没有环绕。 printf()看到一个值为255的int,并相应地打印其十六进制表示(省略前导零)。

#2


4  

The C compiler has to expand the value passed to printf (this is called "promotion"), because printf is a variadic function (it can be called with differing arguments). For values of type char, the promoted value is of type int. Since your compiler's char type seems to be signed, the promoted value is sign extended. In binary:

C编译器必须扩展传递给printf的值(这称为“提升”),因为printf是一个可变参数函数(可以使用不同的参数调用它)。对于char类型的值,提升的值为int类型。由于您的编译器的char类型似乎已签名,因此提升的值是符号扩展的。二进制:

char i = 255           // or: 11111111 in binary
int promoted_i = -1    // or: 11....11111 (usually, 32 or 64 ones)

In the unsigned case, no sign-extension happens:

在未签名的情况下,不会发生符号扩展:

char u = 255           // or: 11111111 in binary, same as above but with different interpretation
unsigned int pu = i    // or: 00....0011111111 (8 ones, preceded by the appropriate number of zeroes) 

#3


0  

char i = 255; invokes implementation-defined behavior by converting a value to a signed type into which it does not fit (assuming char is only 8 bits and plain char is signed, both of which are also implementation-specific.

char i = 255;通过将值转换为不适合的有符号类型来调用实现定义的行为(假设char只有8位且plain char已签名,两者都是特定于实现的。

#4


0  

When you set an 8-bit signed variable to the value 255, which it can't hold, it seems in this case it sets the negative (high-end) flag to 1, so the value would be -1 if it were signed, but then it gets converted to an integer -1 which is ffffffff.

当你将一个8位有符号变量设置为它不能容纳的值255时,在这种情况下它似乎将负(高端)标志设置为1,因此如果它被签名则该值为-1 ,然后它被转换为整数-1,即ffffffff。