长整型和整型在C/C++中有何区别?

81

最近我了解到,在C/C++中,longint的长度相同。简单来说,为什么呢?这似乎对语言来说毫无意义。它是否有任何特定于int的用途呢?我知道我们可以像这样声明一个64位的int

long long x = 0;

但是为什么这种语言要选择这样做,而不是只是让longint更长呢?其他语言例如C#就是这样做的,那么为什么C/C++不呢?


12
我们使用像u8、s16、s32、u64等类型的原因。 - Michael Dorgan
22
在C/C++中,long类型的长度并不总是和int类型相同。C++标准规定,int类型应该是处理器的“自然”大小,但这个大小不一定总是比long类型大。标准还保证了long类型至少和int类型一样长,因此它们长度相等的情况并不总是保证的。 - In silico
7
历史和建筑包袱。相信我,做出类似于你对intlong始终具有相同大小的假设可能会导致问题;我们正在将一个C ++静态库转换为64位架构时,我目前正在修复大量可移植性问题。 - Ed S.
4
我认为所有关于“长”和“短”的说法大都是无意义的。在不同的架构上,长度可能会不同。完全不具可移植性。我认为只应该有一种整数类型(当然要包括有符号和无符号的变体),如果您需要特定大小的任何内容,则应该有固定保证大小的类型(即uint8,uint16等)。 - antred
5
为了好玩我就说一下:在至少使用Atmel的ATmega328微控制器的8位Arduino微控制器开发板上,char是8位、short是16位、int是16位,而long是32位。因此,在这种情况下,shortint是相同的,而long确实更长。 - Gabriel Staples
显示剩余3条评论
5个回答

74

在使用 C 或 C++ 编写时,每个数据类型都与架构和编译器有关。在某些系统中,int 是32位,但你也可以找到它是16位或64位的系统;它没有被定义,所以取决于编译器。

至于 long 和 int,它们来自早期标准整数为16位的时代,其中 long 是32位整数 - 它确实比 int 更长。


14
你说得有些对,但是你没有完整阅读答案。在很久以前的某个时候,在许多平台上intshort的大小是相同的。如果int仍然是16位,那将成为一种“遗留”问题。 int基本上意味着在任何你所在的平台上,它都是表示整数非常高效的大小。 - Omnifarious
2
+1 - 还可以提到这就是为什么C99定义了uintNN_t等类型来澄清事情。 - Brian Roach
4
@MGZero,完全不是这样,这仍然因平台而异,许多平台仍然将intlong定义为不同的大小。 - Mike Graham
8
@Griwes,你暗示这已经是过去时了,事实上现在有很多平台上longint的大小是不同的,未来也没有不会出现这样平台的迹象。你并没有描述C语言中类型大小规则的实际情况。 - Mike Graham
3
@Mike:据我所读,他解释了目前情况的基本原理,这种原理必然可以在过去找到。 - MSalters
显示剩余6条评论

62

以下是具体保证:

  • char 至少占用 8 位 (根据定义,至少为 1 字节,不过可能更多)
  • short 至少占用 16 位
  • int 至少占用 16 位
  • long 至少占用 32 位
  • long long (在支持的版本中) 至少占用 64 位
  • 以上列表中每个类型的宽度 至少 与前一个类型相同(但也可能相同)。

因此,如果需要至少 32 位的类型,则使用 long;如果需要速度合理且至少 16 位的类型,则使用 int

实际上,在 C 中,这些下限是用 范围 表达的,而非大小。例如,语言要求 INT_MIN <= -32767INT_MAX >= +32767。 这个 16 位的要求是由这个和整数用二进制表示的要求得出的。

C99 添加了 <stdint.h><inttypes.h>,定义了诸如 uint32_tint_least32_tint_fast16_t 等类型;这些是 typedef,通常定义为预定义类型的别名。

尺寸和范围之间不一定有直接关系。实现可以将int设置为32位,但仅具有例如-2**23 .. +2^23-1的范围,而其他8位(称为填充位)不对值做出贡献。理论上可能会出现int大于long的情况,只要long具有与int一样宽的范围即可,但在实践中,很少有现代系统使用填充位或其他表示形式而非二进制补码,但标准仍允许这种奇特情况。您在嵌入式系统中更有可能遇到异乎寻常的特性。


然后就有一个问题。因为几乎每个人都认为int将存储32位数字。所以他们通常会把百万放入int变量中。我认为现在每个人都认为它是32位的。如果我们要做到政治正确,每个人都应该开始使用long作为默认数据类型。 - off99555
2
@off99555 没有“默认数据类型”。如果您使用的实现保证int至少为32位,则可以安全地假定它是这样的;所有符合POSIX标准的系统都是如此。如果您做出这种假设,您的代码将无法在具有16位int的系统上移植。这可能是一个好的权衡,也可能不是。(而且,“政治正确”是无关紧要的。) - Keith Thompson

24

long并不等于int。根据规范,long至少与int一样大。例如,在带有GCC的Linux x86_64上,sizeof(long)=8,而sizeof(int)=4。


15

long 不是与 int 相同大小的类型,它的大小至少int相同。引用C++03标准(3.9.1-2):

  

有四种带符号整数类型:“signed char”、“short int”、“int”和“long int”。 在此列表中,每种类型提供至少与列表中前面的类型相同的存储空间。 普通的int具有由执行环境架构建议的自然大小; 提供其他带符号整数类型以满足特殊需求。

我的理解是"只使用int,但如果出于某些原因它无法满足你的需求,并且你有幸找到另一种更适合的整数类型,请随便使用那个类型"。 如果您的计算机体系结构支持更长的整数类型,则可以使用long


1
长整型可能更好的一种情况是,如果你在一个架构上,它需要更长的整数。但实际上并不是这样的。如果你编写可移植代码并且需要至少32位的整数,则long可能更好。根据C标准,long保证不少于32位。而int则没有保证(它可能是16位)。 - Serge Dundich
@SergeDundich:非常正确。对我来说,没有不用C语言回答问题的借口。 - Jon

12

在寻找完全不相关的东西后,偶然发现了这个并需要回答。是的,这很老了,对于稍后浏览的人...

坦率地说,我认为这里所有的答案都不完整。

long 的大小是处理器一次可以操作的位数大小,也称为“字”。半字长是 short。双字长是 long long,是 long 的两倍大(最初仅由供应商实现而不是标准),比 long long 更大的是“四字长”,是 long long 的两倍大,但没有正式名称(也不真正标准)。

那么,int 是从哪里来的?部分来自您处理器上的寄存器,部分来自您的操作系统。您的寄存器定义CPU处理的本机大小,这反过来定义了像 short 和 long 这样的大小。处理器还设计有一个数据大小,这是它最高效的操作大小。应该是 int。

在今天的 64 位机器上,您会认为,既然 long 是一个字,而 64 位机器上的字是 64 位,那么 long 就应该是 64 位,而 int 则是处理器设计要处理的任何大小,但可能不是。为什么?您的操作系统选择了一个数据模型,并为您定义了这些数据大小(基本上是根据它的构建方式)。最终,如果您使用的是 Windows(并使用 Win64),则 long 和 int 均为 32 位。Solaris 和 Linux 使用不同的定义(long 是 64 位)。这些定义称为 ILP64、LP64 和 LLP64 等:

Model      ILP64   LP64   LLP64
int        64      32     32
long       64      64     32
pointer    64      64     64
long long  64      64     64

其中,例如 ILP 表示 int-long-pointer,LLP 表示 long-long-pointer。

为了解决这个问题,大多数编译器似乎支持使用 int32 或 int64 等类型来直接设置整数的大小。

3
“long”的大小是处理器一次可以操作的位数大小。标准并未规定或暗示这一点,并且这并不总是正确的。在一个有16位字长的系统中,需要多条指令才能操作32位数量,仍然需要至少32位的“long”。没有要求“short”是“long”宽度的一半,也没有要求“long long”是“long”的两倍宽度--在我所使用的系统上(16位“short”,64位“long”,64位“long long”)这两个都不是真的。 - Keith Thompson
最终,所有符合标准的C和C++编译器都在<stdint.h>中定义了int32_tint64_t(C语言于1999年引入,后来被C++采用)。这是在假设实现具有支持要求的类型的情况下。并非所有实现都支持。 - Keith Thompson
由于你在评论中没有标记我,所以我直到现在才看到它。事实上,我确实阅读了整个答案。那么我的评论让你觉得我没有阅读吗? - Keith Thompson
这是一个糟糕的答案。它自信地不准确,甚至在内部存在矛盾。 - shirleyquirk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接