Измерение массивов

Одна из основных характеристик массива — это его размер, то есть общее количество элементов в нем. Важно отметить, что для многомерных массивов размер является произведением длин всех его измерений.

Для фиксированных массивов можно рассчитать их размер на стадии компиляции с помощью языковой конструкции на основе оператора sizeof:

sizeof(array) / sizeof(type)

где array — идентификатор, а type — тип массива.

Например, если в коде определен массив fixed:

int fixed[][4] = {{1234}, {5678}};

то его размер равен:

int n = sizeof(fixed) / sizeof(int); // 8

Для динамических массивов это правило не работает, так как оператор sizeof всегда выдает один и тот же размер внутреннего объекта динамического массива: 52 байта.

Обратите внимание, что в функциях все параметры-массивы представлены на внутреннем уровне как объекты-обертки динамических массивов. Это сделано для того, чтобы в функцию можно было передать массив с любым способом распределения памяти, включая и фиксированный. Поэтому sizeof(array) будет выдавать 52 для массива-параметра, даже если через него был передан массив фиксированного размера.
 
Наличие "оберток" сказывается только на sizeof. Функция ArrayIsDynamic всегда правильно определяет категорию фактического аргумента, переданного через массив-параметр.

Для получения размера любого массива на стадии выполнении программы следует использовать функцию ArraySize.

int ArraySize(const void &array[])

Функция возвращает общее количество элементов в массиве. Размерность и типа массива может быть любой. Для одномерного массива вызов функции аналогичен ArrayRange(array, 0) (см. далее).

Если массив распределялся с резервом (третий параметр функции ArrayResize), его величина не берется в расчет.

Пока под динамический массив не выделена память с помощью ArrayResize, функция ArraySize вернет 0. Также нулевым размер становится после вызова для массива ArrayFree.

int ArrayRange(const void &array[], int dimension)

Функция ArrayRange возвращает количество элементов в указанном измерении массива. Размерность и типа массива может быть любой. Параметр dimension должен находиться в пределах от 0 до количества измерений массива минус 1. Индекс 0 соответствует первому измерению, индекс 1 — второму, и так далее.

Произведение всех значений ArrayRange(array, i) с i, пробегающим по всем измерениям, дает ArraySize(array).

Приведем примеры для вышеописанных функций (см. файл ArraySize.mq5).

void OnStart()
{
   int dynamic[];
   int fixed[][4] = {{1234}, {5678}};
   
   PRT(sizeof(fixed) / sizeof(int));   // 8
   PRT(ArraySize(fixed));              // 8
   
   ArrayResize(dynamic10);
   
   PRT(sizeof(dynamic) / sizeof(int)); // 13 (некорректно)
   PRT(ArraySize(dynamic));            // 10
   
   PRT(ArrayRange(fixed0));          // 2
   PRT(ArrayRange(fixed1));          // 4
   
   PRT(ArrayRange(dynamic0));        // 10
   PRT(ArrayRange(dynamic1));        // 0
   int size = 1;
   for(int i = 0i < 2; ++i)
   {
      size *= ArrayRange(fixedi);
   }
   PRT(size == ArraySize(fixed));      // true
}