有符号整数和无符号整数

Signed integer and unsigned integer

我正在学习c语言,有两种不同的整数类型,signed/unsigned。

有符号整数可以表示正数和负数。为什么我们 那么需要无符号整数吗?

  • unsigned 类型有额外的存储位,允许它们的最大幅度为 2CHAR_BIT * sizeof(type) -1 表示正值。这就是为什么像 size_t 这样用来存储文件大小、字符串、数组等的类型是无符号的。

    对于带符号的整数,符号保留一位,因此如果 int 是 32 位长,您只能使用 31 位来存储数字的大小。一个unsigned int没有这个限制; MSB 也用于幅度,但它的代价是不能再为负数。

  • C 标准未定义有符号整数溢出,而无符号整数溢出保证回绕并重置为零。例如,以下代码调用 C:

    中的未定义行为
    int a = INT_MAX;
    a++;
    

    而这保证回绕到零:

    unsigned int a = UINT_MAX;
    a++;
    
  • 无符号类型通常更适合对

  • 执行位操作

一个词的答案是"range"!

当你声明一个带符号的整数时,它需要 4 个字节/32 位内存(在 32 位系统上)。 在这 32 位中,1 位用于符号,其他 31 位表示数字。意味着您可以表示 -2,147,483,648 到 2,147,483,647 之间的任何数字,即 2^31.

如果要用2,147,483,648怎么办?去8个字节?但是如果你对负数不感兴趣,那岂不是浪费了4个字节?

如果您使用 unsigned int,则所有 32 位都代表您的数字,因为您不需要为符号留出 1 位。因此,使用 unsigned int,您可以从 0 到 4,294,967,295,即 2^32

同样适用于其他数据类型。

全靠记忆。它们用于表示更大的数字而不使用更多的内存。

数字以二进制形式存储在计算机上。带符号的数值使用称为二进制补码的过程将正数转换为负数,其中第一位(可以表示最高值的位)在任何计算中都不会被考虑在内。

表示你选择的有符号数字类型最多只能存储N个可用位减1位的最大值,剩余的位将用于确定值的符号,而你选择的无符号类型可以利用其所有可用位来存储其值,但缺点是无法表示负值。

有 two/three 个原因,因为 C 必须为程序员提供最大范围的可能性。

首先,无符号整数相对于其有符号整数可以包含双精度(正)值。我们不想浪费任何一点对吧?

第二个是协议,或者程序必须处理的一些数据结构,可以使用无符号值,所以拥有这种数据类型很方便。

三是处理器其实有无符号类型,所以C语言给了。例如,可能有一些算法会在溢出时进行中继。

可能还有其他动机,可能我不记得了。

就个人而言,我在嵌入式应用程序中大量使用无符号整数。例如,使用单个 unsigned char 作为 256 个元素的循环缓冲区的索引,可以在不检查溢出的情况下简单快速地增加索引,因为当索引溢出时,它会完全按照我的意愿执行(重置为零)。同样,可能还有很多其他情况,我只说第一个想到的。

原因是 Integer 总是有固定的大小。在大多数系统上,整数是 32 位大。

所以无论是有符号整数还是无符号整数,它占用的内存量总是相同的。这就是有符号和无符号的不同之处:范围

无符号整数的范围为 0 到 4294967295 (2³²-1),有符号整数的范围为 -2147483647 到 2147483648