有符号整数(signed int)和无符号整数(unsigned int)之间有什么区别?
有符号整数(signed int)和无符号整数(unsigned int)之间有什么区别?
如您所知,int
在内部存储为二进制。通常,一个int
包含 32 位,但在某些环境中可能包含 16 或 64 位(或者甚至不同的数量,通常但不一定是2的幂)。
但对于此示例,让我们看看 4 位整数。虽然很小,但用于说明目的非常有用。
由于这种整数有四个位,因此它可以假定 16 个值; 16 是 2 的四次幂,或者 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
...这里是四位有符号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
,这一位被称为“符号位”的原因。
(unsigned)(-1)
被要求作为unsigned
类型的最大可表示值(与二进制表示无关),这在二进制补码中显然成立,但在其他表示中可能不成立。 - rubenvb简单来说,无符号整数是一个不可能为负的整数,因此它可以承载更大范围内的正值。有符号整数允许为负,但为了能承载更多的负值,会牺牲一部分正数取值范围。
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
。)
unsigned int num_student;
。使用这样的声明,允许的整数值范围(对于32位编译器)将从范围-2147483648到+2147483647移动到范围0到4294967295。因此,将整数声明为无符号几乎会使它可以容纳的最大可能值的大小增加一倍。实际上,有两个区别:
cout
或在 C 中使用 printf
):无符号整数比特表示被打印函数解释为非负整数。该代码可以使用排序标准识别整数:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");
char
在某些编译器中被认为是 signed
,而在其他编译器中则被认为是 unsigned
。上面的代码使用排序准则来确定编译器中哪个被认为是。如果 a
是无符号的,在执行 a--
后,它将大于 0
,但如果它是有符号的,则会小于零。但在两种情况下,a
的位表示都是相同的。也就是说,在两种情况下,a--
对位表示进行了相同的更改。