我只是想知道我是否应该使用std::size_t for循环之类的东西,而不是int? 例如:
#include <cstdint>
int main()
{
for (std::size_t i = 0; i < 10; ++i) {
// std::size_t OK here? Or should I use, say, unsigned int instead?
}
}
一般来说,关于何时使用std::size_t的最佳实践是什么?
我只是想知道我是否应该使用std::size_t for循环之类的东西,而不是int? 例如:
#include <cstdint>
int main()
{
for (std::size_t i = 0; i < 10; ++i) {
// std::size_t OK here? Or should I use, say, unsigned int instead?
}
}
一般来说,关于何时使用std::size_t的最佳实践是什么?
当前回答
使用std::size_t对c风格数组进行索引/计数。
对于STL容器,你会有(例如)vector<int>::size_type,它应该用于索引和计数vector元素。
实际上,它们通常都是无符号整型,但这并不能保证,特别是在使用自定义分配器时。
其他回答
根据定义,size_t是sizeof操作符的结果。创建Size_t是为了引用大小。
你做某事的次数(在你的例子中是10次)与大小无关,那么为什么要使用size_t呢?Int,或者unsigned Int,应该是可以的。
当然,你在循环中对i做什么也是相关的。例如,如果将它传递给一个接受无符号整型的函数,则选择无符号整型。
在任何情况下,我都建议避免隐式类型转换。使所有类型转换显式。
我一直在努力理解什么时候使用它。但size_t只是一个无符号整型数据类型,它定义在各种头文件中,如<stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, <time.h>, <wchar.h>等。
It is used to represent the size of objects in bytes hence it's used as the return type by the sizeof operator. The maximum permissible size is dependent on the compiler; if the compiler is 32 bit then it is simply a typedef (alias) for unsigned int but if the compiler is 64 bit then it would be a typedef for unsigned long long. The size_t data type is never negative(excluding ssize_t) Therefore many C library functions like malloc, memcpy and strlen declare their arguments and return type as size_t.
/ Declaration of various standard library functions.
// Here argument of 'n' refers to maximum blocks that can be
// allocated which is guaranteed to be non-negative.
void *malloc(size_t n);
// While copying 'n' bytes from 's2' to 's1'
// n must be non-negative integer.
void *memcpy(void *s1, void const *s2, size_t n);
// the size of any string or `std::vector<char> st;` will always be at least 0.
size_t strlen(char const *s);
Size_t或任何无符号类型可能被视为循环变量,因为循环变量通常大于或等于0。
size_t类型是用来指定某个东西的大小,所以使用它是很自然的,例如,获取一个字符串的长度,然后处理每个字符:
for (size_t i = 0, max = strlen (str); i < max; i++)
doSomethingWith (str[i]);
当然,您必须注意边界条件,因为它是无符号类型。顶部的边界通常不那么重要,因为最大值通常很大(尽管有可能达到最大值)。大多数人只使用int型来处理这类事情,因为他们很少有足够大的结构或数组来超过int型的容量。
但要注意以下情况:
for (size_t i = strlen (str) - 1; i >= 0; i--)
这将导致一个无限循环,因为无符号值的包装行为(尽管我看到编译器警告反对这一点)。这也可以通过以下方法来缓解(稍难理解,但至少不会受到包装问题的影响):
for (size_t i = strlen (str); i-- > 0; )
通过将递减转换为延续条件的后检查副作用,这在递减之前对值进行了延续检查,但仍然在循环中使用递减后的值(这就是为什么循环从len ..1而不是镜头1 ..0)。
size_t是一种无符号类型,它可以为您的体系结构保存最大整数值,因此它不会因为符号(有符号int 0x7FFFFFFF加1会得到-1)或短大小(无符号短int 0xFFFF加1会得到0)而导致整数溢出。
它主要用于数组索引/循环/地址算法等。像memset()这样的函数只接受size_t,因为理论上你可能有一个大小为2^32-1的内存块(在32位平台上)。
对于这样简单的循环,不要麻烦,只使用int。
很快,大多数计算机将是64位体系结构,带有64位操作系统,运行在数十亿个元素的容器上的程序。然后必须使用size_t而不是int作为循环索引,否则在32位和64位系统上,索引将在2^32:th元素处换行。
为未来做好准备!