c++中size_t和int的区别是什么?

在几个c++示例中,我看到了类型size_t的使用,而我本应该使用简单的int。有什么不同,为什么size_t应该更好?

163393 次浏览

这是因为size_t可以是int类型以外的任何类型(可能是struct类型)。其思想是将它的工作与底层类型解耦。

友好的维基百科:

stdlib.h和stddef.h头文件定义了一个名为size_t的数据类型,用于表示对象的大小。接受大小的标准库函数期望它们是size_t类型,而sizeof操作符的计算结果为size_t。

size_t的实际类型取决于平台;一个常见的错误是假定size_t与unsigned int相同,这可能导致编程错误,特别是在64位体系结构变得越来越普遍的情况下。

另外,检查为什么size_t很重要

Size_t是用来表示大小的类型(顾名思义)。它依赖于平台(甚至潜在的实现),并且应该仅用于此目的。显然,size_t表示一个大小,是无符号的。许多stdlib函数,包括malloc、sizeof和各种字符串操作函数都使用size_t作为数据类型。

int在默认情况下是有符号的,尽管它的大小也依赖于平台,但在大多数现代机器上它将是一个固定的32位(尽管size_t在64位体系结构上是64位,但int在这些体系结构上仍然是32位)。

总结一下:使用size_t表示对象的大小,在其他情况下使用int(或long)。

SIZE_T的定义可以在下面找到: https://msdn.microsoft.com/en-us/library/cc441980.aspxhttps://msdn.microsoft.com/en-us/library/cc230394.aspx

在这里粘贴所需的信息:

SIZE_T是一个ULONG_PTR,表示指针可以指向的最大字节数。

该类型的声明如下:

typedef ULONG_PTR SIZE_T;

ULONG_PTR是用于指针精度的无符号长类型。在将指针强制转换为长类型以执行指针算术时使用。

该类型的声明如下:

typedef unsigned __int3264 ULONG_PTR;

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位之间的过渡也产生了许多计算机的地址比寄存器宽。我偶尔还会在这里看到关于MS-DOS的Borland Turbo C的问题,它的巨大内存模式将20位地址存储在16位CPU上的32位(但它可以支持80386的32位指令集);摩托罗拉68000有一个16位ALU, 32位寄存器和地址;有15位、24位或31位地址的IBM大型机。您还可以在嵌入式系统中看到不同的ALU和地址总线大小。

任何时候,只要int小于size_t,并且你试图在unsigned int中存储一个非常大的文件或对象的大小或偏移量,就有可能溢出并导致错误。对于int,也有可能得到一个负数。如果intunsigned int更宽,程序将正常运行,但会浪费内存。

如果想要可移植性,通常应该使用正确的类型。很多人会建议你使用有符号数学而不是无符号数学(以避免讨厌的,微妙的错误,如1U < -3)。为此,标准库将<stddef.h>中的ptrdiff_t定义为从另一个指针减去一个指针的结果的有符号类型。

也就是说,一种变通方法可能是根据INT_MAX0INT_MIN适当地检查所有地址和偏移量,并打开编译器关于比较有符号和无符号量的警告,以防您遗漏任何警告。在C语言中,你应该总是,总是检查数组访问是否溢出。