![](/img/trans.png)
[英]what is the difference between “unsigned int *ptr” and signed int *ptr"?
[英]What is the difference between signed and unsigned int
有符号整数和无符号整数有什么区别?
您可能知道, int
以二进制形式在内部存储。 通常int
包含 32 位,但在某些环境中可能包含 16 或 64 位(甚至是不同的数字,通常但不一定是 2 的幂)。
但是对于这个例子,让我们看看 4 位整数。 很小,但对于说明目的很有用。
由于这样的整数有 4 位,因此它可以采用 16 个值之一; 16 是 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
s,当且仅当数字为负时,最高有效位为1
。 这就是为什么,对于有signed int
s,这个位被称为“符号位”。
用外行的话来说,unsigned int 是一个不能为负的整数,因此它可以假设的正值范围更大。 有符号 int 是一个整数,它可以是负数,但具有较低的正范围以换取它可以假设的更多负值。
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
通常具有额外的负值。
也许最重要的区别是有符号和无符号算术的行为。 对于 signed 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
或printf
中的printf
):无符号整数位表示被打印函数解释为非负整数。此代码可以使用排序标准识别整数:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");
char
被认为是signed
一些编译器和unsigned
在其他的编译器。 上面的代码使用排序标准确定在编译器中考虑哪一个。 如果a
是无符号的,在a--
之后,它将大于0
,但如果它是有signed
,它将小于零。 但在这两种情况下,该位表示a
是相同的。 也就是说,在这两种情况下, a--
对位表示进行相同的更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.