14

C 标准保证 anint能够存储每个可能的数组大小。至少,这就是我通过阅读第 6.5.2.1 节第 1 小节(数组下标约束)所理解的:

其中一个表达式应具有类型“指向对象类型的指针”,另一个表达式应具有整数类型,并且结果具有类型“类型”。

既然我们要用ints 作为数组下标,为什么要用 ssize_t来确定数组的大小呢?

为什么strlen()返回size_t什么时候int就足够了?

4

5 回答 5

25

术语“整数类型”并不意味着int- 例如char, 并且short是整数类型。

仅仅因为您可以使用 anint来为数组下标并不一定意味着它可以到达所有可能的数组元素。

更具体地说,关于size_tvs.int的一个例子是平台int可能是 16 位类型,size_t也可能是 32 位类型(或者在当今 64 位平台上更常见的 32 位int与 64 位差异)。size_t

于 2011-05-14T19:54:57.947 回答
6

整数类型不一定是“int”。“long long”也是整数类型,“size_t”也是如此。

数组可以大于 2GB。对于那些编写需要大量内存的程序的人来说,这个属性非常方便,例如具有大缓冲池的 DBMS、具有大内存缓存的应用程序服务器等。大于 2GB/4GB 的数组是 64 位计算的重点:)

strlen() 的 size_t,至少听起来与 C 标准处理数组的方式兼容,无论它是否具有实际意义,或者是否有人见过这么大的字符串,都是另一个问题。

于 2011-05-14T20:02:37.500 回答
2

首先,您从标准中引用的内容并未int具体提及类型。不,int不能保证足以在 C 中存储任何对象(包括数组)的大小。

其次,C 语言实际上并没有专门的“数组订阅”。数组订阅是通过指针算法实现的。并且指针算术中的整数操作数具有ptrdiff_t类型。不是size_t,不是int,而是ptrdiff_t。它是有符号类型,顺便说一句,这意味着该值可以为负数。

第三, 的目的size_t是存储程序中任意对象的大小(即存储 的结果sizeof)。它不会立即用作数组索引。它恰好作为数组索引工作,因为它保证它总是足够大以索引任何数组。但是,从抽象的角度来看,“数组”是一种特定的“容器”,还有其他类型的容器(基于列表的容器、基于树的容器等等)。在一般情况下size_t不足以存储任何容器的大小,这在一般情况下也使其成为数组索引的一个值得商榷的选择。(strlen另一方面,是一个专门与数组一起使用的函数,这在size_t此处很合适。)

于 2011-05-14T20:00:34.220 回答
0

在编写 C 标准时,机器通常具有 16 位“int”类型,并且无法处理任何大于 65535 字节的单个对象,但仍能够处理大于 32767 字节的对象。由于无符号整数上的算术足以处理此类对象的最大大小,但有符号整数上的算术不会,因此将 size_t 定义为无符号以便适应此类对象而无需使用“长”计算。

在最大允许对象大小介于 INT_MAX 和 UINT_MAX 之间的机器上,指向此类对象的开始和结束的指针之间的差异可能太大而无法放入“int”。虽然标准没有对实现应该如何处理它施加任何要求,但一种常见的方法是定义整数和指针环绕行为,这样如果 S 和 E 是指向 char[49152] 的开头和结尾的指针,那么即使 ES 会超过 INT_MAX,它也会产生一个值,当它与 S 相加时,将产生 E。

如今,size_t 是无符号类型这一事实很少有任何真正的优势(因为需要大于 2GB 的对象的代码由于其他原因通常需要使用 64 位指针),并且它会导致涉及对象大小的多种比较行为与直觉相反,但 sizeof 表达式产生无符号类型的事实已经根深蒂固,以至于它永远不会改变。

于 2016-05-06T19:25:45.093 回答
-3

size_t 是无符号整数的 typedef(例如 int 或 long)。

在一些 64 位平台中,int 可以是 32 位,而 size_t 可以是 64 位。

它被用作更标准的尺寸方式。

于 2011-05-14T19:59:33.987 回答