我和c中的size_t搞混了,我知道它是由sizeof操作符返回的。但它究竟是什么?它是数据类型吗?

假设我有一个for循环:

for(i = 0; i < some_size; i++)

我应该用int I吗?或者size_t i;?


当前回答

Size_t和int是不可互换的。例如,在64位Linux上size_t的大小是64位的(即sizeof(void*)),而int是32位的。

还要注意size_t是无符号的。如果你需要签名版本,那么在某些平台上有ssize_t,它与你的例子更相关。

作为一般规则,我建议在大多数情况下使用int,只有在特定需要时才使用size_t/ssize_t(例如mmap())。

其他回答

Size_t和int是不可互换的。例如,在64位Linux上size_t的大小是64位的(即sizeof(void*)),而int是32位的。

还要注意size_t是无符号的。如果你需要签名版本,那么在某些平台上有ssize_t,它与你的例子更相关。

作为一般规则,我建议在大多数情况下使用int,只有在特定需要时才使用size_t/ssize_t(例如mmap())。

根据我的理解,size_t是一个无符号整数,其位大小足以容纳本机体系结构的指针。

So:

sizeof(size_t) >= sizeof(void*)

Size_t是一种可以保存任何数组下标的类型。

根据实现的不同,它可以是:

它没有查尔

无符号短

无符号整型

无符号长

未签名的long long

下面是在我的机器的stddef.h中如何定义size_t:

typedef unsigned long size_t;

Size_t是无符号类型。因此,它不能表示任何负值(<0)。当你在计算某物,并且确定它不是负的时候,你就会用到它。例如,strlen()返回size_t,因为字符串的长度必须至少为0。

在您的示例中,如果循环索引总是大于0,那么使用size_t或任何其他无符号数据类型可能是有意义的。

当使用size_t对象时,必须确保在使用它的所有上下文中(包括算术)都需要非负值。例如,假设你有:

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

你想求出str2和str1的长度之差。你不能:

int diff = s2 - s1; /* bad */

这是因为赋给diff的值总是一个正数,即使s2 < s1,因为计算是用无符号类型完成的。在这种情况下,根据您的用例,对于s1和s2使用int(或long long)可能会更好。

C/POSIX中有一些函数可以/应该使用size_t,但由于历史原因不使用。例如,fgets的第二个参数理想情况下应该是size_t,但它是int。

如果你是经验主义者,

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

输出Ubuntu 14.04 64位GCC 4.8:

typedef long unsigned int size_t;

注意,stddef.h是由GCC提供的,而不是GCC 4.2中src/ GCC /ginclude/stddef.h下的glibc。

有趣的C99外观

Malloc以size_t作为参数,因此它决定了可以分配的最大大小。 由于它也是由sizeof返回的,我认为它限制了任何数组的最大大小。 请参见:C语言中数组的最大大小是多少?