Bad programmers worry about the code. Good programmers worry about data structures and their relationships
среди успешных людей я не встречала нытиков
Барбара Коркоран
ответ ИИ на такое заявление:
Проблемы с точки зрения промышленного программирования:
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.
Bad programmers worry about the code. Good programmers worry about data structures and their relationships
среди успешных людей я не встречала нытиков
Барбара Коркоран
Автору ТС не интерес наш диалог..
Немного очеловечу ИИ, а то как-то мутно про 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
Последний раз редактировалось МихаилГл; 26.11.2025 в 09:40. Причина: Изменение последней строчки кода. Проект не исправлен.