August 2, 2016

Упорядоченные структуры

В TwinCAT 3 система типов данных Data Type Unit (DUT) наконец-то эволюционировала во что-то вменяемое. Теперь она похожа на настоящую и ею удобно пользоваться.


Псевдонимы


ALIAS — позволяет называть другими именами стандартные типы данных.

TYPE FLOAT : REAL;
END_TYPE

или
TYPE DOUBLE : LREAL;
END_TYPE


Структуры


STRUCT — структуры, составные данные. Раньше нельзя было включать в них переменные ввода/вывода:


...а теперь можно:

TYPE ST_DATA :
STRUCT
    In  AT %I* : INT;
    Out AT %Q* : INT;
END_STRUCT
END_TYPE


Структуры стали ближе к классам — теперь их можно расширять:

TYPE ST_DATA_EX EXTENDS ST_DATA :
STRUCT
    Status : INT;
END_STRUCT
END_TYPE

Это сокращает количество кода и позволяет дополнять библиотечные типы данных без излишней копи-пасты:

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


Битовый поля


В структуры можно включать битовые поля, доступные по имени. Для этого существует специальный тип данных BIT. Он занимает ровно 1 бит. На переменную типа BIT нельзя ссылаться указателями и ссылками. Также нельзя использовать их в массивах.


Перечисления


Теперь это глобальная переменная, которая может принимать одно из заранее заданных значений.  Сравните:



Каждое значение имеет свое собственное имя. Имя самого перечисления (E_PI) стало пространством имен этих значений. Теперь нельзя употреблять имена значений (HISTORICAL) без имени перечисления (E_PI).

CASE pi OF
    E_PI.HISTORICAL:
        DrawCircle();

    E_PI.PRECISE:
        DrawRoundCircle();

    E_PI.WARTIME:
        DrawRectangleFast();
END_CASE


Можно задать базовый тип для перечисления, но на выбор только целые типы данных (byte, word, uint, int, и т. п.). Также нельзя использовать псевдонимы (ALIAS) в качестве базовых типов.

TYPE E_PI :
(
    HISTORICAL := 3,
    PRECISE    := 314,
    WARTIME    := 4
) INT;
END_TYPE

По умолчанию, в качестве базового типа выступает INT. Значение первого поля = 0, остальные последовательно увеличиваются на единицу.


Объединение


UNION — для неопределившихся в типе переменной.

TYPE VARIANT :
UNION
    Integer : INT;
    Float   : REAL;
    Double  : LREAL;
    Text    : STRING(4);
END_UNION
END_TYPE

В текущий момент времени, одна переменная позволяет хранить одно значение одного из перечисленных типов данных. Хранится только что-то одно: или целое, или текст, но не одновременно. Другие возможные типы в этот момент хранят мусор и не имеют вменяемого значения. Размер переменной вычисляется по длине самого длинного поля.

v : VARIANT;

[...]

v.Integer := 4;
v.Double  := 3.14;
v.Text    := 'PI';
v.Float   := 1.7;

No comments

Post a Comment

Note: Only a member of this blog may post a comment.