在几个c++示例中,我看到了类型size_t的使用,而我本应该使用简单的int。有什么不同,为什么size_t应该更好?
size_t
int
这是因为size_t可以是int类型以外的任何类型(可能是struct类型)。其思想是将它的工作与底层类型解耦。
从友好的维基百科:
stdlib.h和stddef.h头文件定义了一个名为size_t的数据类型,用于表示对象的大小。接受大小的标准库函数期望它们是size_t类型,而sizeof操作符的计算结果为size_t。 size_t的实际类型取决于平台;一个常见的错误是假定size_t与unsigned int相同,这可能导致编程错误,特别是在64位体系结构变得越来越普遍的情况下。
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
在这里粘贴所需的信息:
SIZE_T是一个ULONG_PTR,表示指针可以指向的最大字节数。
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是无符号的。
sizeof
long int
long long int
历史上有许多其他平台的地址比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,也有可能得到一个负数。如果int或unsigned int更宽,程序将正常运行,但会浪费内存。
unsigned int
如果想要可移植性,通常应该使用正确的类型。很多人会建议你使用有符号数学而不是无符号数学(以避免讨厌的,微妙的错误,如1U < -3)。为此,标准库将<stddef.h>中的ptrdiff_t定义为从另一个指针减去一个指针的结果的有符号类型。
1U < -3
<stddef.h>
ptrdiff_t
也就是说,一种变通方法可能是根据INT_MAX和0或INT_MIN适当地检查所有地址和偏移量,并打开编译器关于比较有符号和无符号量的警告,以防您遗漏任何警告。在C语言中,你应该总是,总是检查数组访问是否溢出。
INT_MAX
0
INT_MIN