在几个 C++ 示例中,我看到了
size_t
类型的使用,而我本来会使用简单的 int
。有什么区别,为什么 size_t
应该更好?
来自友好的维基百科:
stdlib.h 和 stddef.h 头文件定义了一个名为 size_t 的数据类型,用于表示对象的大小。接受大小的库函数期望它们的类型为 size_t,并且 sizeof 运算符的计算结果为 size_t。
size_t 的实际类型与平台相关;一个常见的错误是假设 size_t 与 unsigned int 相同,这可能会导致编程错误,特别是当 64 位架构变得更加流行时。
另外,请检查为什么 size_t 很重要
size_t
1) 是用于表示大小的数据类型(顾名思义),而 2) 依赖于平台(甚至可能是实现),因此应该仅使用 来表示大小.
代表一个尺寸,
size_t
自然是无符号的(你能有一个负3米宽的盒子吗?)。许多 stdlib
函数,包括 malloc
、sizeof
以及各种字符串操作函数都使用 size_t
作为数据类型。
int
默认情况下已签名,尽管其大小也取决于平台,但在大多数现代机器上它将是固定的 32 位(尽管 size_t
在任何 64 位架构上都是 64 位,但 int
在相同的 64 位架构上仍保持 32 位长)。
总结:使用size_t
表示物体的大小,其他情况下使用
int
(或
long
)。请注意,
size_t
是无符号的,而
int
和
long
默认情况下都是带符号的(除非前面加上
unsigned
,或修改为
uint
或
ulong
)。
size_t
类型定义为
sizeof
运算符的无符号整型。在现实世界中,您经常会在 64 位平台上看到
int
定义为 32 位(为了向后兼容),但
size_t
定义为 64 位(因此您可以声明大小超过 4 GiB 的数组和结构)。如果
long int
也是 64 位,则称为 LP64 约定;如果
long int
是 32 位,但
long long int
和指针是 64 位,那就是 LLP64。您也可能得到相反的结果,即使用 64 位指令来提高速度,但使用 32 位指针来节省内存的程序。另外,
int
已签名,
size_t
未签名。历史上有许多其他平台的地址比
int
的原生大小更宽或更短。事实上,在 70 年代和 80 年代初,这种情况比不常见:所有流行的 8 位微型计算机都有 8 位寄存器和 16 位地址,16 和 32 位之间的过渡也产生了许多机器地址比寄存器宽。我偶尔还会在这里看到有关 Borland Turbo C for MS-DOS 的问题,其巨大内存模式在 16 位 CPU 上以 32 位存储 20 位地址(但可以支持 80386 的 32 位指令集); Motorola 68000 有一个 16 位 ALU,带有 32 位寄存器和地址; IBM 大型机有 15 位、24 位或 31 位地址。您还在嵌入式系统中看到不同的 ALU 和地址总线大小。任何时候
int
都小于
size_t
,并且您尝试在
unsigned int
中存储非常大的文件或对象的大小或偏移量,它就有可能溢出并导致错误。对于
int
,也有可能得到负数。如果
int
或
unsigned int
较宽,程序将正确运行,但会浪费内存。如果您想要可移植性,通常应该使用正确的类型。很多人会建议您使用有符号的数学而不是无符号的(以避免像
1U < -3
这样令人讨厌的、微妙的错误)。为此,标准库将
ptrdiff_t
中的
<stddef.h>
定义为指针与另一个指针相减结果的有符号类型。也就是说,解决方法可能是根据
INT_MAX
以及
0
或
INT_MIN
酌情对所有地址和偏移量进行边界检查,并打开有关比较有符号和无符号数量的编译器警告,以防您错过任何内容。无论如何,你应该始终、始终、始终检查 C 语言中的数组访问是否溢出。
SIZE_T
的定义位于:https://msdn.microsoft.com/en-us/library/cc441980.aspx 和 https://msdn.microsoft.com/en-us/library/cc230394.aspx
将所需信息粘贴到此处:
SIZE_T
是
ULONG_PTR
表示指针可以指向的最大字节数。该类型声明如下:
typedef ULONG_PTR SIZE_T;
A
ULONG_PTR
是用于指针精度的无符号长类型。当将指针转换为长类型以执行指针算术时,使用它。该类型声明如下:
typedef unsigned __int3264 ULONG_PTR;