Да, я понимаю. Но мне так больше нравится. Более наглядно, по крайней мере для меня.
ответ ИИ на такое заявление:
Проблемы с точки зрения промышленного программирования:
1. Избыточная вложенность и дублирование структуры
Код использует каскад вложенных IF ... THEN ... ELSE, что:
Трудно читать и поддерживать, особенно при расширении (что будет при in5, in6?).
Сильно нарушает принцип DRY.
Увеличивает когнитивную нагрузку — читателю приходится отслеживать глубину вложенности.
Уязвим к ошибкам при изменении (например, пропущенный END_IF).
⚠️ Замечание: в ST разрешено использовать ELSIF, что существенно улучшает читаемость.
2. Сравнение с = true избыточно
В языках, где переменные имеют тип BOOL, выражение if in0 = true then можно и нужно писать как:
IF in0 THEN
Это стандартная практика и уменьшает шум.
3. Отсутствие масштабируемости
Если завтра понадобится 10 входов — код придётся копипастить. В промышленной среде часто применяют:
массивы (ARRAY[0..4] OF BOOL),
циклы (FOR ... DO),
или даже пользовательские функции/функциональные блоки с параметризацией.
4. «Наглядно для меня» ≠ «наглядно для команды»
В промышленной автоматизации:
Код может поддерживать другой инженер через 2 года.
Часто аудит проводится сторонними специалистами.
Требуется соответствие стандартам (IEC 61131-3) и внутренним гайдлайнам по читаемости.
Настоящая «наглядность» — это когда логика видна с первого взгляда, без отслеживания вложенности на 6 уровней.
Ответ на утверждение автора: «Мне так больше нравится. Более наглядно, по крайней мере для меня»
Это вполне естественное чувство, особенно если человек привык к императивному стилю с вложенными условиями (как в школьных примерах или в C-подобных языках). Однако в промышленном программировании:
"Наглядность" — это не то, что понятно автору сегодня, а то, что будет однозначно понятно любому члену команды завтра.
Ваш вариант — субъективно удобен, но объективно уступает по читаемости, поддерживаемости и соответствию стандартам. Использование ELSIF здесь не просто «стилистика» — это стандартный и рекомендуемый способ реализации приоритетного выбора в ST.
Автору ТС не интерес наш диалог..
Немного очеловечу ИИ, а то как-то мутно про ELSIF
Вот исходное (только убрал =TRUE)Цитата:
... в ST разрешено использовать ELSIF, что существенно улучшает читаемость...
Использование ELSIF здесь не просто «стилистика» — это стандартный и рекомендуемый способ реализации приоритетного выбора в ST...
(пока слезал со стремянки - упал и расплескал пиво)Код:if init then
out := init_flash;
else
if in0 then
out := flash0;
else
if in1 then
out := flash1;
else
if in2 then
out := flash2;
else
if in3 then
out := flash3;
else
if in4 then
out := flash4;
else
out := flash_def;
end_if
end_if
end_if
end_if
end_if
end_if
поскольку это приоритетный выбор - запишу в один уровень
тоже в делфяхКод:if init then out := init_flash;
else if in0 then out := flash0;
else if in1 then out := flash1;
else if in2 then out := flash2;
else if in3 then out := flash3;
else if in4 then out := flash4;
else out := flash_def;
end_if
end_if
end_if
end_if
end_if
end_if
и сяхКод:if init then out := init_flash
else if in0 then out := flash0
else if in1 then out := flash1
else if in2 then out := flash2
else if in3 then out := flash3
else if in4 then out := flash4
else then out := flash_def;
Нравится - все что угодно. Но про наглядность логики (любой вариант) - не говорите.Код:if (init) out = init_flash;
else if (in0) out = flash0;
else if (in1) out = flash1;
else if (in2) out = flash2;
else if (in3) out = flash3;
else if (in4) out = flash4;
else out = flash_def;
Даже упомянутая выше ИИем масштабируемость (пока для си/делфи) для еще десятка входов (без мутилова массива/цикла, туда еще пихать надо) - копи-пасте 10 строк и заполнить с любого будуна сверху вниз 2 столбца цифр.
Но что-то как-то в ST неочень из-за хвоста из END_IF'ов?
Вот для этого в ST и сделан кусочек синтаксического сахара "ELSIF" чтоб превратить убогую белку в изящного хомяка
А сям/делфям такое и не надоКод:if init then out := init_flash;
elsif in0 then out := flash0;
elsif in1 then out := flash1;
elsif in2 then out := flash2;
elsif in3 then out := flash3;
elsif in4 then out := flash4;
else out := flash_def;
end_if
А если смотреть по другому, то нужен массив, сортировка и циклическое мигание с паузой между и так по кругу.
Elsif же прерывает дальнейшую проверку, не? В любых языках.
А не лучше в одну строчку:Код:if init then
out := init_flash;
else
if in0 then
out := flash0;
else
if in1 then
out := flash1;
else
if in2 then
out := flash2;
else
if in3 then
out := flash3;
else
if in4 then
out := flash4;
else
out := flash_def;
end_if
end_if
end_if
end_if
end_if
end_if
Но это только если в коде init, in0, in1 и т.д. - только одно из условий true, остальные должны быть false...Код:out := (init_flash and init) or (flash0 and in0) or (flash1 and in1) or (flash2 and in2) or (flash3 and in3) or (flash4 and in4) or (flash5 and in5) or (flash6 and in6) or (flash7 and in7) or ...;
Решение по ТЗ ТС, но для кодесиса 3.5:
Таск 100 мс:
Первые ARRAY [1..4 всех массивов - это количество кодировокКод:PROGRAM POU_SIG
VAR
HLA_TYP: INT;
HLA_COD: ARRAY [1..4, 1..4] OF INT:= [1, 2, 2, 15, 2, 2, 2, 15, 3, 2, 2, 15, 4, 2, 2, 15];
HLA_IMP: ARRAY [1..4] OF INT:= [0, 0, 0, 0];
HLA_CUR: ARRAY [1..4] OF INT:= [1, 1, 1, 1];
OutX: ARRAY [1..4] OF BOOL:= [1, 1, 1, 1];
OutY: ARRAY [1..4] OF BOOL;
END_VAR
//Программа управления индикаторами с кодировкой
FOR HLA_TYP:= 1 TO 4 DO
HLA_IMP[HLA_TYP]:= HLA_IMP[HLA_TYP] + 1;
IF HLA_IMP[HLA_TYP]= (HLA_CUR[HLA_TYP] * HLA_COD[HLA_TYP, 2] + (HLA_CUR[HLA_TYP] - 1) * HLA_COD[HLA_TYP, 3]) THEN OutX[HLA_TYP]:= FALSE; HLA_CUR[HLA_TYP]:= HLA_CUR[HLA_TYP] + 1; END_IF
IF HLA_IMP[HLA_TYP]= (HLA_CUR[HLA_TYP] * HLA_COD[HLA_TYP, 2] + (HLA_CUR[HLA_TYP] - 1) * HLA_COD[HLA_TYP, 3] - HLA_COD[HLA_TYP, 2]) THEN OutX[HLA_TYP]:= TRUE; END_IF
IF HLA_CUR[HLA_TYP]> HLA_COD[HLA_TYP, 1] THEN HLA_CUR[HLA_TYP]:= 1; END_IF
IF HLA_IMP[HLA_TYP]= (HLA_COD[HLA_TYP, 1] * HLA_COD[HLA_TYP, 2] + (HLA_COD[HLA_TYP, 1] - 1) * HLA_COD[HLA_TYP, 3] + HLA_COD[HLA_TYP, 4]) THEN HLA_IMP[HLA_TYP]:= 0; OutX[HLA_TYP]:= TRUE; END_IF
OutY[HLA_TYP]:= NOT OutX[HLA_TYP];
END_FOR
//Программа управления индикаторами с кодировкой
HLA_COD (ARRAY [1..4, 1..4] OF INT:= [1, 2, 2, 15, 2, 2, 2, 15, 3, 2, 2, 15, 4, 2, 2, 15]) формируемый код
Таск основной программы:
Код:PROGRAM PLC_PRG
VAR
in: ARRAY [0..100] OF BOOL; //наличие аварии для данного кода
blablabla: ton; //таймер на каждую активную аварию
dadada: INT:= 1; //номер шага
nextOK: BOOL;
outizm: BOOL;
i: INT; //Для оптимизации последней строчки
END_VAR
blablabla(in:= NOT blablabla.q, pt:= T#5S); //каждые 5 секунд новую аварию показывать
IF dadada> 100 THEN
dadada:= 1;
END_IF
IF NOT in[dadada] AND NOT nextOK THEN
dadada:= dadada + 1;
IF in[dadada] THEN
nextOK:= TRUE;
END_IF
END_IF
IF blablabla.q THEN
nextOK:= FALSE;
dadada:= dadada + 1;
END_IF
outizm:= (POU_SIG.OutX[1] AND (dadada= 1)) OR (POU_SIG.OutX[2] AND (dadada= 2)) OR (POU_SIG.OutX[3] AND (dadada= 3)) OR (POU_SIG.OutX[4] AND (dadada= 4));
Либо оптимизация для последней строчки:
outizm:= FALSE;
FOR i:= 1 TO 4 DO
outizm:= outizm OR (POU_SIG.OutX[i] AND (dadada= i));
END_FOR