何时使用 `short` 而不是 `int`?

53

有许多问题询问C++中shortint整数类型的区别,但实际上,在什么情况下选择short而不是int呢?

4个回答

70

(详见 Eric的回答,有更详细的解释)

注:

  • 通常情况下,int 被设置为“自然大小”——硬件最高效处理的整数形式。
  • 在数组或算术运算中使用 short 时,会将其转换为 int,这可能会降低处理 short 整数的速度。
  • 如果 shortint 更窄,则使用 short 可以节省内存,这在使用大型数组时非常重要。
  • 在 32 位 int 系统中,与 16 位 int 系统相比,程序将使用更多的内存。

结论:

  • 除非需要严格控制内存,或者您的程序使用了很多内存(例如许多数组),否则请使用 int。在这种情况下,请使用 short

19
注意:不能保证short类型实际上使用的内存比int类型少,这是由具体实现决定的。 - clcto
2
零扩展/符号扩展并非非常昂贵。对于性能损失,我不在意太多。一旦你存储了大量的数字,选择最紧凑适合的类型以节省内存,从而增加缓存局部性。减少缓存未命中的数量通常比从“short”扩展到“int”的成本更重要。 - gexicide
1
如果内存使用非常关键,那么我会分出计数参数并寻找值的合理边界,然后我会使用涵盖该范围的最小整型。使用short仅仅是因为它比较小的模糊概念既有风险(可能太小),也不可靠(可能没有达到你所期望的最小值)。当你对内存使用非常关注以至于要偏离int时,我建议只需使用适当的X[u]intX_t即可。 - user395760
1
@delnan 关于“合理限制”的问题:要注意引入无端限制所带来的“钥匙孔问题”(参见se.ethz.ch/~meyer/publications/OTHERS/scott_meyers/keyhole.pdf)。 - TemplateRex
@TemplateRex 是的,这是一个非常真实的问题,但更糟糕的是,当你随意选择一个 short(或 longchar 或其他类型)时,大多数情况下是因为你甚至没有有意识地设置一个基于现实(或现实的背面版本)的限制,你只是通过引入一个基于平台的、任意的限制来“节省”未知数量的内存,这个限制是基于直觉的。 - user395760
优秀的解释! - Måns Thörnvik

30

当你:

要减小所存储的值的内存占用(例如,如果你针对低内存平台),

  • 想通过增加单个内存页面中可以打包的值的数量(在访问值时减少页面故障)和/或在内存缓存中增加数量(在访问值时减少缓存未命中),来提高性能,并且分析表明有性能收益,
  • 或者你要发送数据到网络或将其存储到磁盘中,并希望减小你的内存占用(以占用更少的磁盘空间或网络带宽)。虽然对于这些情况,你应该优先选择指定确切位数大小的类型,而不是intshort,因为它们可能因平台而异(例如,你需要使用一个具有32位short的平台来读取在具有16位short的平台上编写的文件)。好的候选类型是stdint.h中定义的类型。

并且:

  • 你有一个数字值,它不需要采用目标平台上无法存储在short中的任何值(对于16位short,这是-32768-32767,或者对于16位unsigned short0-65535)。
  • 你的目标平台(或其中一个目标平台)对于short使用的内存比使用int少。标准仅保证short不大于int,因此实现允许对于shortint具有相同的大小。

注意:

char也可用作算术类型。回答“何时应该使用char而不是shortint?”的问题,读者会发现如下所述,但数字不同(对于8位char-128-127,对于8位unsigned char0-255)。

实际上,您可能并不需要特定的short类型。如果您想要一个特定大小的整数,则应优先考虑在 & lt; cstdint & gt; 中定义的类型,例如,int16_t 将在每个系统上都为16位,而无法保证short的大小在编译代码的所有目标平台上都相同。


考虑到上述所有因素,如果要将大量数据写入磁盘,您可能还希望考虑减少磁盘占用空间。 - BernieP
1
不能保证访问一个内存页的短(16位)比int(32位)更快。例如,如果你想从内存中获取一个16位的量,而处理器的字长是32位,那么处理器可能需要将位左移或右移以将它们放置在正确的位置上。 - Thomas Matthews
此外,使用32位获取可能更快地访问内存中的2个16位数量。这取决于内存管理单元。 - Thomas Matthews
@ThomasMatthews 我试图表达的是,访问2048个16位值可能比访问2048个32位值更快,因为前者适合于1个内存页(假设4KB页面),而后者需要2个内存页。有没有其他方法来表达我的答案,使其更清晰?或者你是说我的假设是无效的? - Eric Finn
@EricFinn:还要记住,32位数据类型也满足short的范围条件。在某些编译器和平台上,shortint相同,这意味着当你想要16位时,你得到的是32位。请参见stdint.h中的uint16_tuint32_t数据类型。 - Thomas Matthews
显示剩余2条评论

13
一般来说,你不应该优先选择 short 而非 int int 类型是处理器本地的字长
通常情况下,int 是处理器的字长大小。
例如,在 32 位字长处理器上,int 将是 32 位。处理器使用 32 位最有效率。假设 short 是 16 位,则处理器仍从内存中提取 32 位。这里没有效率;实际上更长了,因为处理器可能必须将位移位以便放置在 32 位字中的正确位置。 选择较小的数据类型
有一些标准化的数据类型是特定长度的比特,例如 uint16_t。这些比起含糊不清的数据类型如 char, short,int 更为受欢迎。这些宽度特定的数据类型通常用于访问硬件或压缩空间(例如消息协议)。 选择较小的范围
short 数据类型基于范围而非位宽。在 32 位系统上,shortint 可能具有相同的 32 位长度。
选择使用 short 的原因之一是值永远不会超过给定范围。这通常是一种错误,因为程序会改变,数据类型可能会溢出。 总结
目前,我不再使用short。当我访问16位硬件设备时,我使用uint16_t。对于数量和循环索引等,我使用unsigned int。当数据存储时需要考虑大小时,我使用uint8_tuint16_tuint32_t。由于short是最小值,因此它在数据存储方面存在歧义。有了stdint头文件的出现,就不再需要使用short了。

1
在 amd64 中,一个“word”是多少位呢?在我的平台上,它是32位,既不是16位的x86汇编“word”,也不是64位处理器的实际本机字长。 - Big Temp
整数的位大小在达到范围(16位)后取决于实现或编译器。一些编译器可能会标准化为32位整数,即使处理器支持更大的大小。告诉编译器确切的目标信息,它将为您的目标平台执行更好的代码优化。 - undefined

0

如果你的架构没有特定的限制,我会建议你始终使用 int。类型 short 是为特定系统设计的,其中内存是宝贵的资源。


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