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