sizeof(arr)/ sizeof(arr [0])如何工作?

Fel*_*lis 28 c++ sizeof

在for循环中查找数组的大小时,我看到人们在写

int arr[10];
for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){}
Run Code Online (Sandbox Code Playgroud)

sizeof(arr) / sizeof(arr[0])阵列的长度如何?它在技术上如何工作?

roz*_*ina 38

如果你有一个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
Run Code Online (Sandbox Code Playgroud)

现场例子

请注意,如果将数组传递给函数,由于数组衰减到指针并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()
Run Code Online (Sandbox Code Playgroud)

实例#2


小智 9

int- 等于 4 个字节
sizeof(int)这意味着:1 * 4 = 4

int arr[10]- 持有 10int
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,就是数组的长度。


Vla*_*cow 7

如C ++标准(5.3.3 Sizeof)中所述

1 sizeof运算符产生其操作数的对象表示形式中的字节数。操作数可以是一个表达式,它是一个未求值的操作数(第5条),或者是带括号的type-id。

在这个表达中

sizeof(arr) / sizeof(arr[0])
Run Code Online (Sandbox Code Playgroud)

在sizeof运算符中使用了两个子表达式。

此子表达式

sizeof(arr)
Run Code Online (Sandbox Code Playgroud)

产生数组占用的字节数arr(我想这arr是一个数组)。

例如,如果您声明了一个数组,例如

int arr[10];
Run Code Online (Sandbox Code Playgroud)

则编译器必须保留内存以容纳10个int类型的元素。例如,如果sizeof( int )等于4,则编译器将保留10 * 4 = 40字节的内存。

子表达

sizeof(arr[0])
Run Code Online (Sandbox Code Playgroud)

给出数组中一个元素占用的字节数。您可以使用任何索引作为示例

sizeof(arr[1000])
Run Code Online (Sandbox Code Playgroud)

因为表达式未评估。仅重要的是运算符内部使用的对象(数组的元素)的大小(以字节为单位)。

因此,如果您知道为数组保留的总字节数

sizeof(arr)
Run Code Online (Sandbox Code Playgroud)

并知道数组的每个元素占用多少字节(数组的所有元素都具有相同的大小),则可以使用公式计算数组中的元素数

sizeof(arr) / sizeof(arr[0])
Run Code Online (Sandbox Code Playgroud)

这是一个简单的关系。如果您有N个类型为T的元素的数组

T arr[N];
Run Code Online (Sandbox Code Playgroud)

并且知道数组占用的内存大小,然后可以使用公式计算其元素的大小

sizeof( arr ) / N == size of an element of the array. 
Run Code Online (Sandbox Code Playgroud)

反之亦然

如果知道数组占用的内存大小及其元素的大小,则可以计算数组中元素的数量

sizeof( arr ) / sizeof( a[0] ) == N - number of elements in the array
Run Code Online (Sandbox Code Playgroud)

您还可以通过以下方式重写最后一个表达式

sizeof( arr ) / sizeof( T ) == N - number of elements in the array
Run Code Online (Sandbox Code Playgroud)

因为数组的元素具有类型T,并且数组的每个元素恰好占用分配T类型的对象所需的字节数。

考虑到通常初学者会犯这样的错误。他们将数组作为参数传递给函数。例如,假设您有一个函数

void f( int a[] )
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

然后将数组传递给函数

int arr[10];
f(arr);
Run Code Online (Sandbox Code Playgroud)

然后该函数使用指向数组第一个元素的指针。实际上函数有声明

void f( int *a )
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您在函数中编写示例

void f( int *a )
{
   size_t n = sizeof( a ) / sizeof( a[0] );
   // ...
}
Run Code Online (Sandbox Code Playgroud)

然后a在函数中是一个指针(它不是数组),那么您将得到类似

void f( int *a )
{
   size_t n = sizeof( int * ) / sizeof( int );
   // ...
}
Run Code Online (Sandbox Code Playgroud)

通常,根据所使用的环境,指针的大小等于8或4个字节。而且您不会得到元素的数量。您将获得一些奇怪的价值。


Bat*_*eba 5

它仅在arr尚未衰减为指针的情况下才有效,也就是说,它是数组类型,而不是指针类型。

sizeof(arr) 是数组占用的总大小。

sizeof(arr[0])是数组中第一个元素的大小。(请注意,C ++中不允许使用零长度数组,因此,如果数组本身存在,则此元素始终存在)。

由于所有元素的大小相同,因此元素的数量为sizeof(arr) / sizeof(arr[0])