Специальные операторы sizeof и typename

sizeof

Оператор sizeof возвращает размер своего операнда в байтах. Синтаксис оператора: sizeof(x), где x может быть типом или выражением. Выражение при этом не вычисляется, так как оператор sizeof выполняется на стадии компиляции, и вместо него в выражение фактически подставляется константа.

Для массивов с фиксированным размером оператор возвращает общий объем выделенной памяти, то есть произведение количества элементов по всем измерениям на размер типа в байтах. Для динамических массивов возвращается размер внутренней структуры, хранящей свойства массива.

Приведем несколько примеров с пояснениями (ExprSpecial.mq5).

double array[2][2];
double dynamic1[][1];
double dynamic2[][2];
Print(sizeof(double));                           // 8
Print(sizeof(string));                           // 12
Print(sizeof("This string is 29 bytes long!"));  // 12
Print(sizeof(array));                            // 32
Print(sizeof(array) / sizeof(double));           // 4 (количество элементов)
Print(sizeof(dynamic1));                         // 52
Print(sizeof(dynamic2));                         // 52

В комментариях помечен результат, выводимый в журнал.

Тип double занимает 8 байт. Размер типа string — 12. В этих 12 байтах хранится служебная информация, о которой мы говорили в разделе про тип string. Такая память резервируется под любую строку (даже неинициализированную). Обратите внимание, что строка с текстом длиной 29 букв, тоже имеет размер 12. Так происходит, потому что внутренняя структура, предназначенная для хранения ссылки на память, имеется как у пустой строки, так и у строки с содержимым. Для получения длины текста следует использовать функцию StringLen.

Размер массива фиксированного размера действительно рассчитан как произведение количества элементов (2*2=4) на размер типа double (8) — итого 32. И как следствие, выражение вида sizeof(array) / sizeof(double) позволяет узнать количество элементов в нем.

Для динамических массивов размер внутренней структуры равен 52 байтам. Различия в описаниях массивов dynamic1 и dynamic2 никак не сказываются на этой величине.  

Оператор sizeof особенно полезен для получения размера классов и структур.

 

typename

Оператор typename возвращает строку с названием типа переданного ей параметра, который может быть типом или выражением. Для массивов, помимо ключевого слова типа данных, выводится признак в виде пары скобок (или нескольких, в зависимости от размерности массива).

Print(typename(double));                         // double
Print(typename(array));                          // double [2][2]
Print(typename(dynamic1));                       // double [][1]
Print(typename(1 + 2));                          // int

Для пользовательских типов, таких как классы, структуры и другие (которые мы изучим в 3-ей Части), имя типа предваряется категорией сущности: например, "class MyCustomType". Кроме того, для констант в строковое описание будет добавлен модификатор "const".

Поэтому, чтобы узнать краткое имя типа, состоящее из одного слова, воспользуйтесь макросом TYPENAME из прилагаемого файла TypeName.mqh.

Узнать имя типа бывает необходимо в так называемых шаблонах, которые способны генерировать из исходного кода похожие реализации для разных типов, задаваемых в параметрах шаблонов.