首先,我所说的“正确定义”是什么意思?
例如,在K&R的《C程序设计语言》第二版中,第2.2节“数据类型和大小”中,他们对整数类型作出了非常明确的陈述:
- 有
short
、int
和long
三种整数类型。它们需要表示不同边界的值。int
是特定硬件的“自然”大小数字,因此可能是最快的。- 整数类型
short
、int
和long
的大小完全取决于实现。- 但它们有限制。
short
和int
至少应该容纳16位。long
至少应该容纳32位。short
>=int
>=long
。
这非常明确和明显。但对于 size_t
类型并非如此。在 K&R 5.4 地址算术中,他们说:
- ...
size_t
是由sizeof
运算符返回的无符号整数类型。sizeof
运算符产生其操作数类型的对象所需的字节数。
在 C99标准草案 中,在6.5.3.4 sizeof运算符中,他们说:
- 结果的值是实现定义的,其类型(无符号整数类型)为
size_t
,定义在<stddef.h>
(和其他标题)中。
在7.17 公共定义中:
在7.18.3 其他整数类型的限制中:
size_t
是 sizeof 运算符的无符号整数类型的结果;
还有一篇有用的文章 - 为什么size_t很重要。它说:
- size_t的极限值是
SIZE_MAX
,为65535
我理解的是,
- 好的,让我们试着想象一下,如果没有
size_t
会怎样。- 例如,让我们从
<string.h>
标准库中取出void *memcpy(void *s1, void const *s2, size_t n);
函数。- 我们用
int
代替n
参数中的size_t
。- 但是内存的大小不能为负数,所以最好使用
unsigned int
。- 很好,看起来我们现在很满意,没有了
size_t
也可以。- 但是
unsigned int
有限制的大小——如果有些机器可以复制大于unsigned int
所能容纳的内存块怎么办?- 好吧,那么我们就使用
unsigned long
,现在我们满意了吗?- 但是对于那些操作更小内存块的机器而言,
unsigned long
将会效率低下,因为对于它们来说,long
不是“自然”的类型,必须执行额外的操作才能使用long
。- 所以这就是为什么我们需要
size_t
——用来表示特定硬件一次能够操作的内存大小。在某些机器上,它将等于int
,在其他机器上则等于long
,具体取决于它们使用哪种类型最有效。
size_t
严格绑定了 sizeof
运算符。因此,size_t
表示对象的最大字节数。它也可能表示特定 CPU 型号一次可以移动的字节数。
但是,这里仍然有很多谜团:
- C 语言中,“对象”是什么意思?
- 为什么它被限制为 65535,这是可以由 16 位表示的最大数字?embedded.com 上的文章说,
size_t
也可以是 32 位。 - K&R 说,
int
对于平台来说具有“自然”的大小,它可以等于int
或long
。那么如果它是“自然的”,为什么不使用它而不是size_t
?
更新
有类似的问题:
但是它的答案没有提供清晰的定义或权威来源链接(如果不计算维基百科)。
我想知道何时使用size_t
,何时不使用size_t
,为什么引入它,以及它真正代表什么。
size_t
至少为16位,但可能更多。 - KninnugSIZE_MAX
的常见定义。请注意,“常见”在这里可能意味着大约在1990年左右比较普遍的定义。 - dhke