似乎它们都占用了 4 个字节的空间,
那么有什么区别呢?
首先,未指定 int/long 的大小。所以在你的编译器上, anint
和 along
可能是相同的,但这在编译器中并不通用。
unsigned long
至于和之间的区别long
:
假设 4 个字节, along
的范围为-2,147,483,648
to 2,147,483,647
。无符号长整数的范围为0
to 4,294,967,295
。
另一个区别是溢出。对于有符号类型,溢出具有未指定的行为。但是对于无符号类型,溢出肯定会“环绕”。
C 语言规范允许 int 和 long 类型的实现在几个约束内从一个平台到另一个平台有所不同。这种可变性对于跨平台代码来说是一个令人头疼的问题,但它也是一种资产,因为它使知情的程序员能够在本机处理器速度和不提供两者的硬件架构上的完整数值范围之间平衡他们的设计目标。
通常,“int”应该映射目标 CPU 体系结构机器的机器寄存器大小,以便加载、存储和操作 int 类型数据应直接转换为使用目标处理器的本机寄存器的操作。
为了节省内存空间, int 可以小于机器寄存器大小(大 int 占用的 RAM 是小 int 的两倍)。即使在与旧系统的兼容性和内存效率是高优先级的 64 位架构上,通常也将 int 视为 32 位实体。
“long”的大小可以与“int”相同或更大,具体取决于目标体系结构的寄存器大小。如果目标架构不支持其本机机器寄存器中的大值,则可以在软件中实现对“long”的操作。
如今,为提高能效或嵌入式设备而设计的 CPU 芯片是 int 和 long 之间的区别。用于台式机或笔记本电脑等通用 CPU 的编译器通常将 int 和 long 视为相同的大小,因为 CPU 有效地使用 32 位寄存器。在手机等较小的设备上,CPU 可以更自然地处理 16 位数据,并且必须努力处理 32 位或更大的数据。
每个寄存器更少的位意味着芯片上需要更少的电路,更少的数据线将数据移入和移出芯片,更低的功耗和更小的芯片裸片尺寸,所有这些都可以降低成本(以美元和瓦特为单位) .
在这样的架构中,您很可能会发现 int 的大小为 16 位,而 long 的大小为 32 位。也可能存在与使用 long 相关的性能损失,这是由于等待状态以通过 16 位数据总线在多次读取中加载 32 位,或者由于在软件中实现长操作(加法、减法等)导致的,如果本机hardware 不支持硬件中的此类操作。
作为一般规则,关于 int 和 long 的唯一假设是 int 的范围在任何架构上都应始终小于或等于 long。您还应该假设有一天您的代码将针对不同的架构重新编译,您当前在 int 和 long 之间看到的任何关系都不再存在。
这就是为什么即使在日常的普通编码中也应该小心地将 int 与 long 分开。它们今天可能完全兼容分配,因为它们在您当前的硬件平台上的实现细节是一致的,但不能保证在所有平台上都是一致的。
unsigned long
好吧,和之间的区别long
很简单——上限。签名long
从(在平均 32 位系统上)大约 -21 亿 (-2^31) 到 +21 亿 (+2^31 - 1),而unsigned long
从 0 到 42 亿 (2^32 - 1)。
碰巧在许多编译器和操作系统(显然包括您的)上,int
它也是一个 32 位值。但是 C++ 标准没有确定任何这些类型的最大宽度,只有最小宽度。在某些系统上,int
是 16 位。在某些系统上,long
是 64 位。其中很多取决于目标处理器架构,以及它的基本字长是多少。
头文件的limits.h
存在是为了定义当前编译环境下各种类型的最大容量,并且stdint.h
存在是为了提供与环境无关的类型保证宽度,例如int32_t
.