Подтвердить что ты не робот

Как работает sizeof (arr)/sizeof (arr [0])?

Когда вы ищете размер массива в цикле for, я видел, как люди пишут

int arr[10];
for(int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++){}

Как sizeof(arr)/sizeof(arr[0]) длина массива? Как это технически работает?

4b9b3361

Ответ 1

Если у вас есть 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()

ЖИВОЙ ПРИМЕР № 2

Ответ 2

Как описано в C++ Standard (5.3.3 Sizeof)

1 Оператор sizeof дает количество байтов в представлении объекта его операнда. Операндом является либо выражение, которое является неоцененным операндом (раздел 5), либо идентификатором типа в скобках.

В этом выражении

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])

Вот простое соотношение. Если у вас есть массив из N элементов типа T

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.

Примите в acccount что обычно новички делают такую ошибку. Они передают массив как аргумент функции. Например, предположим, что у вас есть функция

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 байтам в зависимости от используемой среды. И вы не получите количество элементов. Вы получите какую-то странную ценность.

Ответ 3

Он работает только в том случае, если arr не был разложен в указатель, т.е. Это тип массива, а не тип указателя.

sizeof(arr) - это общий размер, занимаемый массивом.

sizeof(arr[0]) - размер первого элемента массива. (Обратите внимание, что массивы нулевой длины не разрешены в C++, поэтому этот элемент всегда существует, если сам массив существует).

Поскольку все элементы будут иметь одинаковый размер, число элементов равно sizeof(arr)/sizeof(arr[0]).

Ответ 4

При работе с массивом (some_type name[some_size]) sizeof(name) - сколько байтов занимает массив. Разделение общего размера массива на размер одного элемента (sizeof(name[0])) дает вам количество элементов в массиве.

Ответ 5

c++ способ использования экстента, который позволяет u получить количество элементов в N-м измерении массива. см. http://en.cppreference.com/w/cpp/types/extent для подробностей

int values[] = { 1 };

std::extent<decltype(values)>::value == 1

Ответ 6

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, и это длина массива.