![](/img/trans.png)
[英]How to understand “vector<int> avector (arr, arr + sizeof(arr) / sizeof(arr[0]) )”?
[英]How do sizeof(arr) / sizeof(arr[0]) work?
在 for 循环中寻找数组的大小时,我看到人们写
int arr[10];
for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){}
sizeof(arr) / sizeof(arr[0])
数组的长度是多少? 它在技术上如何运作?
如果您有一个array
则sizeof(array)
返回数组占用的字节数。 由于每个元素可能占用超过 1 个字节的空间,因此您必须将结果除以一个元素的大小 ( sizeof(array[0])
)。 这为您提供了数组中的元素数。
例子:
std::uint32_t array[10];
auto sizeOfInt = sizeof(std::uint32_t); // 4
auto numOfBytes = sizeof(array); // 10*sizeOfInt = 40
auto sizeOfElement = sizeof(array[0]); // sizeOfInt = 4
auto numOfElements = sizeof(array) / sizeof(array[0]); // numOfBytes / sizeOfElement = 40 / 4 = 10
请注意,如果您将数组传递给函数,则上述方法将不起作用,因为数组衰减为指针并且sizeof(array)
返回指针的大小。
std::size_t function(std::uint32_t a[]) // same for void function(std::uint32_t a[10])
{
return sizeof(a); // sizeof(std::uint32_t*)!
}
std::uint32_t array[10];
auto sizeOfArray = function(array); // array decays to a pointer inside function()
正如 C++ 标准 (5.3.3 Sizeof) 中所述
1 sizeof 运算符产生其操作数的对象表示中的字节数。 操作数要么是一个表达式,它是一个未计算的操作数(第 5 条),要么是一个带括号的类型 ID。
在这个表达式中
sizeof(arr) / sizeof(arr[0])
使用了两个带有 sizeof 运算符的子表达式。
这个子表达式
sizeof(arr)
产生数组arr
占用的字节数(我认为arr
是一个数组)。
例如,如果您声明了一个数组,如
int arr[10];
那么编译器必须保留内存以容纳 10 个 int 类型的元素。 例如,如果sizeof( int )
等于 4,那么编译器将保留 10 * 4 = 40 字节的内存。
子表达式
sizeof(arr[0])
给出数组中一个元素占用的字节数。 例如,您可以使用任何索引
sizeof(arr[1000])
因为表达式是未评估的。 仅重要的是运算符内部使用的对象(数组的元素)的字节大小。
因此,如果您知道为数组保留的总字节数
sizeof(arr)
并知道数组的每个元素占用多少字节(数组的所有元素具有相同的大小)然后您可以使用公式计算数组中的元素数
sizeof(arr) / sizeof(arr[0])
这是一个简单的关系。 如果你有一个 T 类型的 N 个元素的数组
T arr[N];
并且您知道数组占用的内存大小,然后您可以使用公式计算其元素的大小
sizeof( arr ) / N == size of an element of the array.
反之亦然
如果知道数组所占用的内存大小及其元素的大小,则可以计算数组中的元素数
sizeof( arr ) / sizeof( a[0] ) == N - number of elements in the array
您也可以通过以下方式重写最后一个表达式
sizeof( arr ) / sizeof( T ) == N - number of elements in the array
因为数组的元素具有类型 T,并且数组的每个元素占用的字节数恰好是分配类型 T 的对象所需的字节数。
考虑到通常初学者会犯这样的错误。 他们将数组作为参数传递给函数。 例如,假设您有一个函数
void f( int a[] )
{
// ...
}
然后你将你的数组传递给函数
int arr[10];
f(arr);
然后函数使用指向数组第一个元素的指针。 实际上该函数有声明
void f( int *a )
{
// ...
}
因此,如果您在函数中编写例如
void f( int *a )
{
size_t n = sizeof( a ) / sizeof( a[0] );
// ...
}
那么作为函数内的a
是一个指针(它不是一个数组)那么你会得到类似的东西
void f( int *a )
{
size_t n = sizeof( int * ) / sizeof( int );
// ...
}
通常指针的大小等于 8 或 4 个字节,具体取决于使用的环境。 你不会得到元素的数量。 你会得到一些奇怪的值。
int
- 等于 4 个字节
sizeof(int)
意思是:1 * 4 = 4
int arr[10]
- 持有 10 个int
sizeof(arr)
的含义是:10×4 = 40,我们得到了10 int
和每int
得到4个字节,, arr
而不[]
这意味着所有的arr
。
sizeof(arr[0])
意思是:1 * 4 = 4
sizeof(arr) / sizeof(arr[0])
= 10*4 / 1*4 = 10,就是数组的长度。
它仅在arr
没有衰减为指针时才有效,即它是数组类型,而不是指针类型。
sizeof(arr)
是数组占用的总大小。
sizeof(arr[0])
是数组中第一个元素的大小。 (请注意,C++ 中不允许零长度数组,因此如果数组本身存在,则该元素始终存在)。
由于所有元素的大小相同,因此元素数量为sizeof(arr) / sizeof(arr[0])
。
处理数组( some_type name[some_size]
)时, sizeof(name)
是数组占用的字节数。 将数组的总大小除以一个元素的大小 ( sizeof(name[0])
) 得出数组中有多少个元素。
c++ 使用范围的方式,它允许您获取数组第 N 维中的多个元素。 有关详细信息,请参阅http://en.cppreference.com/w/cpp/types/extent
int values[] = { 1 };
std::extent<decltype(values)>::value == 1
让我们举个例子,比如arr[]={1,2,4,3,5}
。
那么数组的大小将是 5 并且arr[0]
的大小将是“1”,因为它包含一个元素。 基本上它是一个子数组,从上面的问题来看,它将是 5/1,它将自动返回数组的大小 =5。
区别在于 int arr[5] = {1,2,3,4,5}; 这里arr是指向数组的指针, &arr[0]是Integer类型的指针
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.