首先,我的意思是'正确定义'?
例如,“C编程语言”第2版中的K& R,在 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 standard draft, 6.5.3.4 sizeof运算符中,他们说:
- 结果的值是实现定义的,其类型(无符号整数类型)是
size_t
,在<stddef.h>
中定义(和其他 头)。
7.17通用定义:
size_t
,这是sizeof运算符的结果的无符号整数类型;
7.18.3其他整数类型的限制:
- size_t
的限制SIZE_MAX
65535
还有一篇有用的文章 - Why size_t matters。它说:
- 好的,让我们试着想象一下,如果没有
size_t
会是什么。- 例如,我们从
获取void *memcpy(void *s1, void const *s2, size_t n);
<string.h>
标准函数- 我们使用
int
代替size_t
n
参数。- 但是记忆的大小不能是负数,所以最好采取
unsigned int
。- 很好,好像我们现在很开心,没有
size_t
。- 但是
unsigned int
的大小有限 - 如果有一台机器可以复制大于unsigned int
的内存块呢?- 好的,我们现在使用
unsigned long
,现在我们很开心吗?- 但对于那些使用较小内存块运行的计算机,
unsigned long
效率低下,因为long
不是“自然” 对于他们来说,他们必须执行额外的操作才能使用long
秒。- 因此,我们需要
size_t
- 来表示内存大小,特定硬件可以同时运行。在某些机器上它会 等于int
,在其他人 - 等于long
,具体取决于哪种类型 他们最有效率。
我从中理解的是size_t
与sizeof
运算符严格限制。因此size_t
表示对象的最大大小(以字节为单位)。它也可能表示特定CPU模型可以同时移动的字节数。
但这里仍有许多神秘之处:
size_t
也可能是32位。int
平台具有“自然”大小,可以等于int
或long
。那么,如果它是“自然的”,为什么不使用它代替size_t
?有类似的问题:
但是它的答案并未提供明确的定义或与权威来源的链接(如果不算维基百科那样)。
我想知道何时使用size_t
,什么时候不使用size_t
,为何引入它,以及它真正代表什么。
答案 0 :(得分:3)
就C而言,“对象”是什么?
“对象”是一个定义的术语。 C99标准将其定义为:“执行环境中的数据存储区域,其内容可以表示值”(第3.14节)。一个更通俗的定义可能是“存储在内存中的价值”。对象具有不同的大小,具体取决于存储的值的类型。该类型不仅包括char
和int
等简单类型,还包括结构和数组等复杂类型。例如,数组的存储是对象,其中每个元素都是对象。
为什么它被限制为65535,这是最大数字,可以用16位表示? embedded.com上的文章说,size_t也可能是32位。
你误解了。重新阅读第7.18.3节的前两段。 SIZE_MAX
表示类型size_t
的最大值,但其实际值取决于实现。标准中给出的值是 minimum 值。在大多数实现中,它更大。
K&amp; R说,int具有平台的“自然”大小,并且它可以等于int或long。那么,如果它是“自然的”,为什么不使用它而不是size_t?
因为没有特别的原因,对象的最大大小应限制在单个机器字中可表达的字节数(这几乎与“自然大小”的含义相同)。在int
和long
大小不同的情况下,也不清楚哪一个应与size_t
对应,如果有的话。使用size_t
而不是其中一个摘要远离计算机详细信息并使您的代码更具可移植性。
响应更新:
我想知道,何时使用size_t,何时不使用size_t,为何引入它以及它实际代表什么。
size_t
主要定义为sizeof
的结果类型。因此,它“真正代表”的是对象的大小。
使用size_t
保存表示对象大小或与对象大小相关的值。这显然是它的用途。在大多数情况下,您可以通过类型匹配来完成此操作:使用类型size_t
的变量来存储声明为具有该类型的值,例如某些函数的返回值(例如strlen()
)和某些运营商的结果(例如sizeof
)。
请勿将size_t
用于表示对象大小以外的其他值或与其密切相关的值(例如对象大小的总和或正差异)。
答案 1 :(得分:2)
为什么它被限制为65535,这是最大数字,可以用16位表示?
至少16位。
根据1999 ISO C标准(C99),size_t是至少16位的无符号整数类型(参见7.17和7.18.3节)。
为什么要使用size_t
?
size_t
是一种保证包含任何数组索引的类型。
size_t
可以是任何一个(也可以是除此之外的任何其他内容)unsigned char
,unsigned short
,unsigned int
,unsigned long
或{{1根据实施情况而定。
要使用unsigned long long
或unsigned int
代替unsigned long
,原因类似于它们不是唯一的无符号整数类型。
其目的是减轻程序员不必担心哪些预定义类型用于表示大小。
在一个系统上,使用size_t
表示大小可能是有意义的;另一方面,使用unsigned int
或unsigned long
可能更有意义。
因此,使用unsigned long long
增加了代码可能更具可移植性的优势。
答案 2 :(得分:2)
何时使用
size_t
使用size_t
表示非负索引,并使用可追溯到sizeof
表达式的值。
何时不使用
size_t
每当某个值可能为负时,例如当你减去指针时。这允许指针指向同一个数组,但它可能会产生一个负数,具体取决于指针的相对位置。为此情况定义了另一种类型ptrdiff_t
。
为什么要介绍
标准的设计者可以选择引入单独的类型,或者要求现有类型能够容纳尺寸。第一种选择为编译器编写者提供了更大的灵活性,因此设计人员采用了单独的类型。
它真正代表什么
它能够表示内存中对象的大小,可以是数组,struct
,struct
数组,struct
s数组,或其他任何东西。大小以字节表示。
该类型也非常方便用于非负索引,因为它可以表示最大粒度的任何大小的结构的索引(即,char
的最大可能数组的索引,因为该标准要求char
具有尽可能小的1
}。
答案 3 :(得分:1)
没有(单一)“正确的定义”。如上所述,它的实现已定义。
我想知道,何时使用size_t,
与size_t
和sizeof()
相关的所有内容。也就是说,对象的技术规模。
何时不使用size_t,
用于正常(面向域)计数和数字。
为什么它被引入以及它真正代表什么。
它提供了一种独立于实现的方式来处理大小和分配,即它允许您编写可移植代码。