signed和unsigned int有什么区别?
答案 0 :(得分:87)
您可能知道,int
内部存储在二进制文件中。通常int
包含32位,但在某些环境中可能包含16位或64位(或者甚至是不同的数字,通常但不一定是2的幂)。
但是对于这个例子,我们来看看4位整数。很小,但有助于说明目的。
由于这样的整数有四位,因此它可以采用16个值中的一个; 16是2到4的幂,或2次2次2次2.这些值是什么?答案取决于此整数是signed int
还是unsigned int
。使用unsigned int
时,该值永远不会为负数;没有与该值相关联的符号。以下是四位unsigned int
的16个可能值:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
...以下是四位signed int
的16个可能值:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
正如您所看到的,对于signed int
,当且仅当数字为负时,最重要的位是1
。这就是为什么,对于signed int
s,这个位被称为“符号位”。
答案 1 :(得分:12)
int
和unsigned int
是两种不同的整数类型。 (int
也可以称为signed int
,或仅signed
; unsigned int
也可以称为unsigned
。)
顾名思义,int
是签名的整数类型,unsigned int
是无符号整数类型。这意味着int
能够表示负值,unsigned int
只能表示非负值。
C语言对这些类型的范围提出了一些要求。 int
的范围必须至少为-32767
.. +32767
,unsigned int
的范围必须至少为0
.. 65535
。这意味着两种类型必须至少为16位。它们在许多系统上是32位,甚至在某些系统上是64位。由于大多数现代系统使用的二进制补码表示,int
通常具有额外的负值。
也许最重要的区别是有符号算术与无符号算术的行为。对于签名的int
,溢出具有未定义的行为。对于unsigned int
,没有溢出;产生超出类型范围的值的任何操作都会换行,例如UINT_MAX + 1U == 0U
。
任何整数类型(有符号或无符号)都可以模拟无限数学整数集的子范围。只要您处理类型范围内的值,一切正常。当您接近某个类型的下限或上限时,会遇到不连续性,并且可能会出现意外结果。对于有符号整数类型,问题仅出现在非常大的负值和正值上,超过INT_MIN
和INT_MAX
。对于无符号整数类型,非常大的正值和零会出现问题。这可能是错误的来源。例如,这是一个无限循环:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
因为i
总是大于或等于零;这是无符号类型的本质。 (在循环内部,i
为零时,i--
将其值设置为UINT_MAX
。)
答案 2 :(得分:10)
有时我们事先知道存储在给定整数变量中的值总是为正 - 例如,当它用于计算事物时。在这种情况下,我们可以将变量声明为无符号,如unsigned int num student;
。通过这样的声明,允许的整数值范围(对于32位编译器)将从范围-2147483648转移到+2147483647到范围0到4294967295.因此,将整数声明为无符号几乎将最大可能的大小加倍否则它可以持有的价值。
答案 3 :(得分:8)
在外行人的术语中,无符号整数是一个不能为负的整数,因此它可以假定的正值范围更大。 signed int是一个整数,可以是负数但具有较低的正范围,以换取它可以假设的更多负值。
答案 4 :(得分:1)
实际上,有两个区别:
cout
或在C中使用printf
):打印函数将无符号整数位表示形式解释为非负整数。此代码可以使用排序条件识别整数:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");