为什么size_t当int足以满足数组的大小?
C标准保证int
能够存储每个可能的数组大小。 至少,这是我从阅读§6.5.2.1,第1小节(数组下标约束)中理解的内容:
其中一个表达式应具有类型”指向对象类型的指针”,另一个表达式应具有整数类型,结果具有类型”type”。
既然我们将int
s用作数组下标,为什么我们应该使用size_t
来确定数组的大小?
为什么strlen()
在int
足够时返回size_t
?
术语“整数类型”并不意味着int
– 例如, char
, short
是整数类型。
仅仅因为你可以使用int
来下标数组并不一定意味着它可以到达所有可能的数组元素。
更具体地说,关于size_t
与int
,一个例子是平台,其中int
可能是16位类型, size_t
可能是32位类型(或更常见的32位int
与今天64位的64位size_t
差异)平台)。
整数类型不一定是“int”。 “long long”也是一个整数类型,“size_t”也是如此。
数组可以大于2GB。 对于那些编写内存饥饿程序的人来说,这个属性非常方便,例如带有大缓冲池的DBMS,带有大内存缓存的应用程序服务器等。大于2GB / 4GB的arrays是64位计算的全部要点:)
strlen()的size_t,至少与C标准处理数组的方式兼容,是否具有实际意义,或者是否有人看到过大的字符串,这是另一个问题。
首先,您从标准中引用的内容并未特别指出对int
类型的引用。 不, int
不能保证足以在C中存储任何对象(包括数组)的大小。
其次,C语言并没有特别具有“数组订阅”。 数组订阅是通过指针算法实现的。 指针算术中的积分操作数有ptrdiff_t
类型。 不是size_t
,不是int
,而是ptrdiff_t
。 它是一个带符号的类型,BTW,意味着该值可以是负数。
第三, size_t
的目的是存储程序中任何对象的大小(即存储sizeof
的结果)。 它不是立即用作数组索引。 它恰好作为一个数组索引工作,因为它保证它总是足够大,可以索引任何数组。 但是,从抽象的角度来看,“数组”是一种特定的“容器”,还有其他类型的容器(基于列表的容器,基于树的容器等)。 在通用情况下, size_t
不足以存储任何容器的大小,这在一般情况下也使得它成为数组索引的可疑选择。 (另一方面, strlen
是一个专门用于数组的函数,这使得size_t
适用于那里。)
编写C标准时,机器通常具有16位“int”类型,并且无法处理任何大于65535字节的单个对象,但仍然能够处理大于32767字节的对象。 由于对unsigned int的算术足够大以处理这些对象的最大大小,但是对signed int的算术不会,size_t被定义为无符号的,以便容纳这些对象而不必使用“长”计算。
在最大允许对象大小介于INT_MAX和UINT_MAX之间的机器上,指向此类对象的开头和结尾的指针之间的差异可能太大而不适合“int”。 虽然标准没有强制实现应该如何处理它的任何要求,但常见的方法是定义整数和指针环绕行为,这样如果S和E是指向char [49152]的开头和结尾的指针,那么即使ES超过INT_MAX,它也会产生一个值,当加到S时,它将产生E.
如今,size_t是一个无符号类型的事实很少有任何真正的优势(因为需要大于2GB的对象的代码通常需要使用64位指针,因为其他原因)并且它导致涉及对象大小的多种比较表现反直觉地说,但sizeof表达式产生无符号类型的事实已经足够根深蒂固,以至于不可能改变。
size_t是无符号整数的typedef(例如int或long)。
在某些64位平台中,int可以是32位,而size_t可以是64位。
它被用作尺寸的更标准方式。