【发布时间】:2010-03-31 03:37:28
【问题描述】:
它们似乎都占用了 4 个字节的空间,
那有什么区别呢?
【问题讨论】:
标签: c syntax integer long-integer
它们似乎都占用了 4 个字节的空间,
那有什么区别呢?
【问题讨论】:
标签: c syntax integer long-integer
首先,int/long 的大小是未指定的。所以在你的编译器上,int 和 long 可能是相同的,但这在编译器中并不通用。
至于unsigned long和long的区别:
假设 4 个字节,long 的范围为 -2,147,483,648 到 2,147,483,647。无符号长整数的范围为 0 到 4,294,967,295。
另一个区别是溢出。对于有符号类型,溢出具有未指定的行为。但是对于无符号类型,溢出肯定会“环绕”。
【讨论】:
4,294,967,296 在答案和@Dan 的评论中都应该是4,294,967,295。
C 语言规范允许 int 和 long 类型的实现在几个限制内从一个平台到另一个平台有所不同。这种可变性对于跨平台代码来说是一个令人头疼的问题,但它也是一种资产,因为它使知情的程序员能够在本机处理器速度和硬件架构上的完整数值范围之间平衡他们的设计目标,而硬件架构不能同时提供这两者。
一般来说,“int”应该映射目标 CPU 架构机器的机器寄存器大小,因此加载、存储和操作 int 类型数据应该直接转换为使用目标处理器的本机寄存器的操作。
为了节省内存空间,Int 可以小于机器寄存器大小(大整数占用的 RAM 是小整数的两倍)。即使在 64 位架构上,也很常见将 int 视为 32 位实体,其中与旧系统的兼容性和内存效率是高优先级。
“long”的大小可以与“int”相同或更大,具体取决于目标体系结构的寄存器大小。如果目标架构不支持其本机机器寄存器中的大值,则可以在软件中实现对“long”的操作。
如今,您可以在其中发现 int 和 long 之间的区别,专为提高电源效率或嵌入式设备而设计的 CPU 芯片。用于台式机或笔记本电脑等通用 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。
【讨论】:
int 和long 都具有相同的长度——基本字长。对吗?