int8_t、int_least8_t和int_fast8_t的区别是什么?

75

int8_t、int_least8_t和int_fast8_t这三种int类型有什么区别呢?


为什么你在这里有很好的答案时却接受了一个错误的答案? - Jim Balter
7
实际上,除了你所接受的答案外,这里每一个答案都是正确且具有信息量的。 - Jim Balter
@Jim,我的答案不正确,但并不像大家想的那样错误。我唯一错的是int_least8_t。无论如何,我已经编辑过来了,现在是正确的。 - Earlz
@Earlz 换句话说,它对于 int8_t 是正确的,但其他所有东西都是错误的。至于“每个人似乎都认为”的内容,你和我都不知道,但是因为你的回答没有得到应有的负评,所以可能并不是那么多人这样认为。 - Jim Balter
5个回答

82

在 Carl Norum 引用的 C99 标准的章节中定义了这些差异。但是举个例子可能会很有用。

假设您有一个适用于 36 位系统的 C 编译器,其中 char = 9 位,short = 18 位,int = 36 位,long = 72 位。那么:

  • int8_t 不存在,因为没有办法满足仅使用 正好 8 个值位而不进行填充的约束条件。
  • int_least8_tchar 的 typedef。而不是 shortint,因为标准要求使用至少 8 位的 最小 类型。
  • int_fast8_t 可以是任何东西。如果认为 "本机" 大小很快,则可能是 int 的 typedef。

66

来自规范部分7.8.1.1 精确宽度整型,第1段:

typedef名称intN_t表示具有宽度N、无填充位和二进制补码表示法的有符号整数类型。因此,int8_t表示具有确切8位宽度的有符号整数类型。

另外,来自:7.18.1.2 最小宽度整型,第1段:

typedef名称int_leastN_t表示具有至少宽度N的有符号整数类型,没有比指定宽度更小的有符号整数类型。因此,int_least32_t表示具有至少32位宽度的有符号整数类型。

最后来自于 7.18.1.3 最快的最小宽度整型,第2段:

typedef名称int_fastN_t表示具有至少N宽度的最快有符号整数类型。typedef名称uint_fastN_t表示具有至少宽度N的最快无符号整数类型。


28

这里有一个概念上简单的答案:对于所有三种类型,int*N_t 的宽度必须 >= N。 intN_t 具有 确切的 N 位,int_leastN_t 是 最少(最窄)的此类类型,而 int_fastN_t 是 最快 的此类类型。

例如,在具有8位字节和32位快速寄存器的机器上,int8_t 和 int_least8_t 别名为signed char,但 int_fast8_t 别名为int32_t。 而如果实现选择定义它们,int_least24_t 和 int_fast24_t 都将别名为int32_t,而 int24_t 则未定义。

编辑:正如下面的Technophile指出的那样,快速类型真正的问题是内存,而不是寄存器(通常,对寄存器低位的操作与整个寄存器一样快)。例如,写入内存中的int8_t可能需要加载包含它的32位字,仅修改字节,然后将其写回,而如果它存储在32字中,则可以在无需读取的情况下写入。


3
只有在阅读了这个答案之后,我才意识到 int_fastN_t 类型的重要性。N 位寄存器。然而,这是非常明显的,但对于来自面向对象世界(Java)的人来说,很难在一开始就意识到这一点(至少是独自意识到)。 - Kohányi Róbert
3
这段话的意思是:“Java之所以不需要使用寄存器(register)是因为它是一种与机器无关的(抽象)编程语言,这并不是因为Java是面向对象的(C++也是)。因此,在Java中,“register”的概念相当无意义(也被禁止使用)。” - user1284631
@axeoth 你说得对,这与面向对象无关,但这些类型的整个重点,尤其是最小和快速版本,是机器独立性。Java实际上更加机器相关,因为它的int类型是具体的--它们有预定义和固定的大小...在没有8位字节的机器上实现Java是不可能的。而寄存器的问题并不相关...寄存器不是C内存模型的一部分,“register”关键字被大多数编译器忽略,但C和Java编译器当然都会生成寄存器代码。 - Jim Balter
3
这可能与内存访问有关。例如,假设内存是64位字。考虑如何将8位、16位或32位值写入内存位置:处理器可能需要读取内存,修改所需的位,然后写入64位值,而64位值可以在单次访问中写入。 - Technophile
1
这是唯一一个尝试回答我来这里寻求解答的问题的答案,所以我很惊讶它没有更多的赞。我猜想这就是'fast'的作用,但我想要确认,所以谢谢大家证实了它与CPU操作和RAM访问细节有关。 - RTHarston

23

intN_t(以及uintN_t)并非所有C99实现都需要。这些类型是“精确宽度整数类型”。它们在适用的实现中是必需的(基本上是每台桌面计算机)。

对于值为8、16、32和64的N,所有C99实现都需要int_leastN_t。这是“最小宽度整数类型”。

对于值为8、16、32和64的N,所有C99实现都需要int_fastN_t。这是“最快的最小宽度整数类型”。


1
这样做更好,因为它添加了必须符合的内容和可选内容。我给加一分。 - Anurag Kalia

2

这些与整数的大小相关,正如它们听起来的那样。

int8_t is exactly 8 bits
int_least8_t is the smallest int type that has at least 8 bits
int_fast8_t is the fastest int type that has at least 8 bits.

4
这并没有真正解释区别,而这也是原问题的重点。 - Conrad Meyer
@Jim Balter:根据这个答案,int_least8_tint_fast8_t有什么区别? - Conrad Meyer
2
@Conrad 答案仅仅缺少第二行的“是最小类型”的字眼。嗯。 - Jim Balter
@Conrad 是的,没错。你以为 int_least8_t 可能是 long long 吗?int8_t 被解释为精确的,int_fast8_t 被解释为最快的;这解释了其中2/3的差异。对于 int_least8_t 的解释有缺陷,但只要花费最少的努力,就可以轻松理解。 - Jim Balter
@Conrad 顺便说一句,被采纳的答案,关于它们为什么首先存在的解释,当时被接受时是极其错误的,即使在编辑之后,它仍然有着你所声称的导致它不能“用来解释差异”的同样缺陷。对那个答案的关键评论指出了它的问题所在。 - Jim Balter
上面的评论指的是Earlz最初被接受的答案,但现在已被删除。 - Jim Balter

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