Здесь показаны различия между двумя версиями данной страницы.
| Both sides previous revision Предыдущая версия Следущая версия | Предыдущая версия | ||
|
help:conditional [2023/01/02 14:27] aleks_versus |
help:conditional [2025/09/28 18:37] (текущий) aleks_versus [Проблема висячего else] |
||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | + | [[help:tuples|Назад: Кортежи]] | |
| - | [[help:regexp|Назад: Регулярные выражения]] | + | |
| ====== Условия ====== | ====== Условия ====== | ||
| + | Условия — это такие особые конструкции в **QSP**, которые позволят сделать вашу игру по настоящему интерактивной. Они позволяют разветвлять события, происходящие в игре в зависимости от уже сложившихся условий, и таким образом вносить разнообразие в игровой процесс. Операторы, которые используются в конструкциях условий, в программировании называются **операторами ветвления**. | ||
| - | Условия — это такие особые конструкции в **QSP**, которые позволят сделать вашу игру по настоящему интерактивной. Они позволяют разветвлять события, происходящие в игре в зависимости от уже сложившихся условий, и таким образом вносить разнообразие в игровой процесс. Операторы, которые используются для в конструкциях условий, в программировании называются **операторами ветвления**. | + | Операторы ветвления часто используют с [[help:expressions|операциями сравнения и с логическими операциями]]. |
| ===== Операторы условий ===== | ===== Операторы условий ===== | ||
| - | * ''**IF**'' — основной оператор для записи конструкций условий. Конструкции, записываемые с помощью этого оператора (назовём их "простыми условиями"), имеют две формы: однострочную и многострочную, — и в общем виде выглядят так:<sxh qsp> | + | * ''%%IF%%'' — основной оператор для записи конструкций условий. Конструкции, записываемые с помощью этого оператора (назовём их "простыми условиями"), имеют две формы: однострочную и многострочную, — и в общем виде выглядят так: <sxh qsp> |
| - | ! однострочная форма записи | + | ! однострочная форма записи |
| - | IF [#выражение]: {команда 1} & {команда 2} & ... | + | IF [#выражение]: {команда 1} & {команда 2} & … |
| + | ! многострочная форма записи | ||
| + | IF [#выражение]: | ||
| + | {команда 1} | ||
| + | {команда 2} | ||
| + | … | ||
| + | END | ||
| + | </sxh> В данном случае, если верно условие ''[#выражение]'', выполняются команды ''{команда 1}'', ''{команда 2}'' и т.д. Для однострочной формы записи это будут только те команды, которые идут в той же строке, что и оператор ''IF'' до конца строки; а для многострочной формы записи это будут те команды, которые идут в последующих строках после двоеточия и до специального ключевого слова ''END''. | ||
| + | * В качестве условия могут выступать операции сравнения, логические операции и иные выражения, возвращающие числовые значения. | ||
| + | * Ключевое слово ''%%END%%'' при многострочной форме записи должно стоять отдельной строкой. | ||
| + | * Если условие ''%%[#выражение]%%'' не верно, команды выполнены не будут. | ||
| + | * Примеры однострочной формы записи условий: <sxh qsp> | ||
| + | ! если сумма a и b равна двум, | ||
| + | ! переменной c присваивается значение 30 | ||
| + | if a+b=2: c=30 | ||
| + | ! Если в инвентаре нет апельсина, выводится текст | ||
| + | if no obj "Апельсин": pl "У Вас нет апельсина." | ||
| + | ! это тоже простая однострочная форма | ||
| + | if ((a+b)/c)=45+54 or (b<5 or c>45) and no obj 'лопата' and $f=$vvv+'RRRRR': p 'OK' & goto 'Next' | ||
| + | </sxh> | ||
| + | * Примеры многострочной формы записи условий: <sxh qsp> | ||
| + | if библиотека = 0: | ||
| + | узнал_о_тусовке = 0 | ||
| + | библиотека_вернулся = 1 | ||
| + | gt 'библиотека' | ||
| + | end | ||
| + | if a+b=2: | ||
| + | c=30 | ||
| + | end | ||
| + | </sxh> | ||
| + | * **Обратите внимание!!!** При многострочной форме записи после двоеточия в той же строке, в какой находится оператор ''%%IF%%'', не должны идти никакие команды, иначе плеер посчитает такой оператор условия однострочным, и команды в последующих строках будут выполняться в любом случае, независимо от того, верным окажется условие или нет. Пример такой ошибочной записи: <sxh qsp> | ||
| + | if библиотека = 0: узнал_о_тусовке = 0 | ||
| + | библиотека_вернулся = 1 &! эта строчка будет выполняться в независимости от верности условия | ||
| + | gt 'библиотека' &! и эта | ||
| + | end &! ключевое слово end - просто игнорируется | ||
| + | </sxh> | ||
| + | * ''%%ELSE%%'' — ключевое слово, использующееся совместно с оператором ''%%IF%%'', и которое служит для предоставления альтернативы, если условие не выполнено. Ключевое слово ''%%ELSE%%'' так же имеет две формы записи: однострочную и многострочную. Многострочную форму записи ''%%ELSE%%'' можно использовать только в многострочной конструкции оператора ''%%IF%%'', тогда как однострочную форму записи можно использовать как в однострочной, так и в многострочной, конструкции оператора ''%%IF%%''. Общая форма записи: <sxh qsp> | ||
| + | ! однострочная форма записи | ||
| + | IF [#выражение]: {команда д1} & {команда д2} & … ELSE {команда н1} & {команда н2} & … | ||
| - | ! многострочная форма записи | + | ! в многострочном IF |
| - | IF [#выражение]: | + | ! многострочная форма ELSE |
| - | {команда 1} | + | IF [#выражение]: |
| - | {команда 2} | + | {команда д1} |
| + | {команда д2} | ||
| ... | ... | ||
| - | END | + | ELSE |
| - | </sxh> В данном случае, если верно условие ''[#выражение]'', выполняются команды ''{команда 1}'', ''{команда 2}'' и т.д. Для однострочной формы записи это будут только те команды, которые идут в той же строке, что и оператор ''**IF**'' до конца строки; а для многострочной формы записи это будут те команды, которые идут в последующих строках после двоеточия и до специального ключевого слова ''**END**''. | + | {команда н1} |
| - | * В качестве условия могут выступать операции сравнения, логические операции и иные выражения, возвращающие числовые значения. | + | {команда н2} |
| - | * Ключевое слово ''**END**'' при многострочной форме записи должно стоять отдельной строкой. | + | ... |
| - | * Если условие ''[#выражение]'' не верно, команды выполнены не будут. | + | END |
| - | * Примеры однострочной формы записи условий:<sxh qsp> | + | ! однострочная форма ELSE |
| - | ! если сумма a и b равна двум, | + | IF [#выражение]: |
| - | ! переменной c присваивается значение 30 | + | {команда д1} |
| - | if a+b=2: c=30 | + | {команда д2} |
| - | ! Если в инвентаре нет апельсина, выводится текст | + | ... |
| - | if no obj "Апельсин": pl "У Вас нет апельсина." | + | ELSE {команда н1} & {команда н2} & ... |
| - | ! это тоже простая однострочная форма | + | ! команды в следующих строках |
| - | if ((a+b)/c)=45+54 or (b<5 or c>45) and no obj 'лопата' and $f=$vvv+'RRRRR': p 'OK' & goto 'Next' | + | ! до END игнорируются |
| + | END | ||
| + | </sxh> Здесь, если условие''[#выражение]'' верно, выполняются команды от двоеточия до ключевого слова ''ELSE'', а если условие ''[#выражение]'' не верно, выполняются команды от ключевого слова ''ELSE'' и до конца конструкции условия. | ||
| + | * После ''%%ELSE%%'' можно ставить, а можно не ставить двоеточие. | ||
| + | * При однострочной форме записи: | ||
| + | * и команды и ключевое слово ''%%ELSE%%'' должны быть записаны в одной строке | ||
| + | * окончанием альтернативного списка команд является конец строки. | ||
| + | * если однострочная форма записи ''%%ELSE%%'' используется в многострочной форме записи ''%%IF%%'', все команды, которые идут в последующих строках после ''%%ELSE%%'' до ''%%END%%'' игнорируются. | ||
| + | * Примеры однострочной записи: <sxh qsp> | ||
| + | ! если сумма a и b равна двум, переменной c присваивается значение 30 | ||
| + | ! в противном случае (то есть если сумма a и b не равна двум) | ||
| + | ! переменной c присваивается значение 10 | ||
| + | if a+b=2: c=30 else c=10 | ||
| + | ! в зависимости от того есть ли в инвентаре апельсин | ||
| + | ! выводится соответствующий текст | ||
| + | if obj "Апельсин": pl "У Вас есть апельсин." else pl "У Вас нет апельсина." | ||
| + | ! однострочная форма else внутри многострочной if | ||
| + | if $левая_рука = 'Великий меч': | ||
| + | gosub 'atack', 300 | ||
| + | gosub 'health.prove' | ||
| + | gosub 'win.prove' | ||
| + | else gosub 'atack', atack_power | ||
| + | end | ||
| </sxh> | </sxh> | ||
| - | * Примеры многострочной формы записи условий:<sxh qsp> | + | * При многострочной форме записи: |
| - | if библиотека = 0: | + | * все команды должны идти в последующих строках после ''%%ELSE%%''; |
| - | узнал_о_тусовке = 0 | + | * Примеры многострочной записи: <sxh qsp> |
| - | библиотека_вернулся = 1 | + | if a+b=2: |
| - | gt 'библиотека' | + | c=30 |
| - | end | + | else |
| - | + | c=10 | |
| - | if a+b=2: | + | end |
| - | c=30 | + | if obj "Апельсин": |
| - | end | + | pl "У Вас есть апельсин." |
| + | else | ||
| + | pl "У Вас нет апельсина." | ||
| + | end | ||
| + | if len($curtoken) > 0: | ||
| + | $tokens[curtoken_num] = $curtoken tokens_count = curtoken_num + 1 | ||
| + | else | ||
| + | tokens_count = curtoken_num | ||
| + | end | ||
| </sxh> | </sxh> | ||
| - | * Обратите внимание!!! При многострочной форме записи после двоеточия в той же строке, в какой находится оператор ''**IF**'', не должны идти никакие команды, иначе плеер посчитает такой оператор условия однострочным, и команды в последующих строках будут выполняться в любом случае, независимо от того, верным окажется условие или нет. Пример такой ошибочной записи:<sxh qsp> | + | * ''%%ELSEIF%%'' — ключевое слово, которое используется совместно с оператором ''%%IF%%'' и позволяет определять на одном уровне вложенности последовательно-исключающие условия. Ключевое слово ''%%ELSEIF%%'' имеет однострочную и многострочную формы записи. Многострочную форму записи можно использовать только в многострочных конструкциях с оператором ''%%IF%%'', а однострочную — как в многострочных, так и в однострочных конструкциях с оператором ''%%IF%%''. Общие формы записи: <sxh qsp> |
| - | if библиотека = 0: узнал_о_тусовке = 0 | + | ! однострочная в однострочном условии |
| - | библиотека_вернулся = 1 &! эта строчка будет выполняться в независимости от верности условия | + | IF [#выражение 1]: {набор команд 1} ELSEIF [#выражение 2]: {набор команд 2} ELSE {последний набор команд} |
| - | gt 'библиотека' &! и эта | + | ! многострочная в многострочном условии |
| - | end &! ключевое слово end - просто игнорируется | + | IF [#выражение 1]: |
| - | </sxh> | + | {набор команд 1} |
| - | * ''**ELSE**'' — ключевое слово, использующееся совместно с оператором ''**IF**'', и которое служит для предоставления альтернативы, если условие не выполнено. Условия с ключевым словом ''**ELSE**'' (назовём это "сложным условием") так же имеют две формы записи: однострочную и многострочную, — и в общем виде выглядят так:<sxh qsp> | + | … |
| - | ! однострочная форма записи | + | ELSEIF [#выражение 2]: |
| - | IF [#выражение]: {команда д1} & {команда д2} & ... ELSE {команда н1} & {команда н2} & ... | + | {набор команд 2} |
| - | !многострочная форма записи | + | … |
| - | IF [#выражение]: | + | ELSEIF … : |
| - | {команда д1} | + | … |
| - | {команда д2} | + | ELSE |
| - | ... | + | {последний набор команд} |
| - | ELSE | + | … |
| - | {команда н1} | + | END |
| - | {команда н2} | + | |
| - | ... | + | |
| - | END | + | |
| - | </sxh> Здесь, если условие ''[#выражение]'' верно, выполняются команды от двоеточия до ключевого слова ''**ELSE**'', а если условие [#выражение] не верно, выполняются команды от ключевого слова ''**ELSE**'' и до конца конструкции условия. | + | |
| - | * При однострочной форме записи: | + | |
| - | * и команды и ключевое слово ''**ELSE**'' должны быть записаны в одной строке | + | |
| - | * ключевое слово ''**END**'' не нужно | + | |
| - | * окончанием конструкции условия является конец строки. | + | |
| - | * Примеры однострочной записи:<sxh qsp> | + | |
| - | ! если сумма a и b равна двум, переменной c присваивается значение 30 | + | |
| - | ! в противном случае (то есть если сумма a и b не равна двум) | + | |
| - | ! переменной c присваивается значение 10 | + | |
| - | if a+b=2: c=30 else c=10 | + | |
| - | ! в зависимости от того есть ли в инвентаре апельсин | + | |
| - | ! выводится соответствующий текст | + | |
| - | if obj "Апельсин": pl "У Вас есть апельсин." else pl "У Вас нет апельсина." | + | |
| - | </sxh> | + | |
| - | * При многострочной форме записи: | + | |
| - | * все команды должны идти в последующих строках после двоеточия, | + | |
| - | * ключевое слово ''**ELSE**'' должно быть записано отдельной строкой, | + | |
| - | * конструкция условия должна оканчиваться ключевым словом ''**END**'', записанным отдельной строкой | + | |
| - | * Примеры многострочной записи:<sxh qsp> | + | |
| - | if a+b=2: | + | |
| - | c=30 | + | |
| - | else | + | |
| - | c=10 | + | |
| - | end | + | |
| - | + | ||
| - | if obj "Апельсин": | + | |
| - | pl "У Вас есть апельсин." | + | |
| - | else | + | |
| - | pl "У Вас нет апельсина." | + | |
| - | end | + | |
| - | if len($curtoken) > 0: | + | ! однострочная в многострочном условии |
| - | $tokens[curtoken_num] = $curtoken | + | IF [#выражение 1]: |
| - | tokens_count = curtoken_num + 1 | + | {набор команд 1} |
| - | else | + | … |
| - | tokens_count = curtoken_num | + | ELSEIF [#выражение 2]: {набор команд 2} & … |
| - | end | + | ELSEIF … : … |
| + | ELSE {последний набор команд} | ||
| + | END | ||
| + | </sxh> Работает это следующим образом. Если ''[#выражение 1]'' верно, выполняются команды ''{набор команд 1}''. Если ''[#выражение 1]'' неверно, но верно ''[#выражение 2]'', выполняются команды ''{набор команд 2}'', и т.д. И только если неверны все выражения в текущей конструкции условия, выполнятся команды после ''ELSE''. Верность выражения ''[#выражение 1]'' не исключает верности выражения ''[#выражение 2]'', однако верность выражения ''[#выражение 2]'' исключает верность выражения ''[#выражение 1]''.\\ Особенности записи ''ELSEIF'': | ||
| + | * Может использоваться вариант написания ''%%ELSE IF%%''. Работает точно так же. | ||
| + | * Если в многострочной конструкции ''%%IF%%'' после ''%%ELSEIF%%'' операторы идут в той же самой строке (однострочная форма), то все последующие строки игнорируются до следующего ''%%ELSEIF%%'', либо до ''%%ELSE%%'' или ''%%END%%''. | ||
| + | * В конструкции ''%%IF%%'' c ''%%ELSEIF%%'' может как присутствовать, так и отсутствовать часть с ''%%ELSE%%''. | ||
| + | * Примеры: <sxh qsp> | ||
| + | IF ОЧКИ>124: | ||
| + | GOTO 'КОН3' | ||
| + | ELSEIF ОЧКИ>99: | ||
| + | GOTO 'КОН4' | ||
| + | ELSE | ||
| + | GOTO 'КОН5' | ||
| + | END | ||
| + | |||
| + | if money mod 10=1 and money mod 100<>11: | ||
| + | *pl "У вас <<money>> монета." | ||
| + | elseif money mod 10>1 and money mod 10<5 and (money mod 100<5 or money mod 100>20): | ||
| + | *pl "У вас <<money>> монеты." | ||
| + | elseif money mod 10=0 or money mod 10>4 or (money mod 100>10 and money mod 100<21): | ||
| + | *pl "У вас <<money>> монет." | ||
| + | end | ||
| + | </sxh> Пример записи ''ELSEIF'' с операторами в той же строке: <sxh qsp> | ||
| + | if r = 0: | ||
| + | 'Вариант 0' | ||
| + | elseif r = 1: 'Вариант 1' | ||
| + | elseif r = 2: 'Вариант 2' | ||
| + | elseif r = 3: 'Вариант 3' | ||
| + | else: 'Без вариантов' | ||
| + | end | ||
| </sxh> | </sxh> | ||
| - | * ''**ELSEIF**'' — ключевое слово, которое используется совместно с оператором ''**IF**'' и позволяет определять на одном уровне вложенности последовательно-исключающие условия. Ключевое слово ''**ELSEIF**'' можно использовать только в многострочных конструкциях (это обещали исправить в более поздних версиях): <sxh qsp> | + | * ''%%END%%'' — ключевое слово, которое указывает на конец многострочной конструкции условия. Допускается запись ''%%END IF%%''. Не используется для однострочных форм записи. |
| - | IF [#выражение 1]: | + | |
| - | {набор команд 1} | + | |
| - | ... | + | |
| - | ELSEIF [#выражение 2]: | + | |
| - | {набор команд 2} | + | |
| - | ... | + | |
| - | ELSEIF ... : | + | |
| - | ... | + | |
| - | ELSE | + | |
| - | {последний набор команд} | + | |
| - | ... | + | |
| - | END | + | |
| - | </sxh> Работает это следующим образом. Если ''[#выражение 1]'' верно, выполняются команды ''{набор команд 1}''. Если ''[#выражение 1]'' неверно, но верно ''[#выражение 2]'', выполняются команды ''{набор команд 2}'', и т.д. И только если неверны все выражения в текущей конструкции условия, выполнятся команды после ''**ELSE**''. Верность выражения ''[#выражение 1]'' не исключает верности выражения ''[#выражение 2]'', однако верность выражения ''[#выражение 2]'' исключает верность выражения ''[#выражение 1]''.\\ Правила записи такие же, как и для других видов многострочных условий: | + | |
| - | * После двоеточия в той же строке, где находится оператор ''**IF**'' или ''**ELSEIF**'' не должно идти никаких команд, только со следующей строки. | + | |
| - | * Вся конструкция должна заканчиваться оператором ''**END**'', стоящим в отдельной строке. | + | |
| - | * В конструкции может как присутствовать, так и отсуствовать часть с ''**ELSE**''. | + | |
| - | * Примеры:<sxh qsp> | + | |
| - | IF ОЧКИ>124: | + | |
| - | GOTO 'КОН3' | + | |
| - | ELSEIF ОЧКИ>99: | + | |
| - | GOTO 'КОН4' | + | |
| - | ELSE | + | |
| - | GOTO 'КОН5' | + | |
| - | END | + | |
| - | </sxh><sxh qsp> | + | |
| - | if money mod 10=1 and money mod 100<>11: | + | |
| - | *pl "У вас <<money>> монета." | + | |
| - | elseif money mod 10>1 and money mod 10<5 and (money mod 100<5 or money mod 100>20): | + | |
| - | *pl "У вас <<money>> монеты." | + | |
| - | elseif money mod 10=0 or money mod 10>4 or (money mod 100>10 and money mod 100<21): | + | |
| - | *pl "У вас <<money>> монет." | + | |
| - | end | + | |
| - | </sxh> | + | |
| - | * ''**END**'' — ключевое слово, которое указывает на конец многострочной конструкции условия. Допускается запись ''**END IF**''. Не используется для однострочных форм записи. | + | |
| - | Для многострочных форм записи допускается вложенность неограниченной глубины. Каждый уровень вложения должен заканчиваться своей строкой ''**END**''. | + | Для многострочных форм записи допускается вложенность неограниченной глубины. Каждый уровень вложения должен заканчиваться своей строкой ''%%END%%''. |
| Некоторые примеры: | Некоторые примеры: | ||
| + | |||
| <sxh qsp> | <sxh qsp> | ||
| - | if a+b<3 or y=8: | + | if a+b<3 or y=8: |
| - | p 'A+B<3 или Y=8' | + | p 'A+B<3 или Y=8' |
| - | nl | + | nl |
| - | if j=88: nl & p 'NEXT' | + | if j=88: nl & p 'NEXT' |
| - | if $h='ooo': | + | if $h='ooo': |
| - | p 'loo' & jump 'lll' | + | p 'loo' & jump 'lll' |
| - | end | + | end |
| - | end | + | end |
| </sxh> | </sxh> | ||
| <sxh qsp> | <sxh qsp> | ||
| - | if a=0: | + | if a = 0: |
| - | 'abc1234' | + | 'abc1234' |
| - | if b=0: '0' else '1' | + | if b = 0: '0' else '1' |
| - | if j=88: nl & p 'NEXT' | + | if j = 88: nl & p 'NEXT' |
| - | if $h='ooo': | + | if $h='ooo': |
| - | p 'loo' & jump 'lll' | + | p 'loo' & jump 'lll' |
| - | else | + | else |
| - | p 'sample text' | + | p 'sample text' |
| - | v=8 | + | v = 8 |
| - | end | + | end |
| - | 1234 | + | 1234 |
| - | else | + | else: |
| - | '01234' | + | '01234' |
| - | g=78 | + | g = 78 |
| - | end | + | end |
| </sxh> | </sxh> | ||
| Строка 176: | Строка 208: | ||
| </sxh> | </sxh> | ||
| - | Пример реализации однострочного варианта ''**ELSEIF**'' с последовательным перечислением вложенных условий через ''**ELSE IF**'': | + | Пример реализации однострочного варианта ''%%ELSEIF%%'': |
| <sxh qsp> | <sxh qsp> | ||
| - | if n=0: *pl "Ноль" else if n=1: *pl "Один" else if n=2: *pl "Два" | + | if n=0: *pl "Ноль" elseif n=1: *pl "Один" elseif n=2: *pl "Два" |
| </sxh> | </sxh> | ||
| Несколько примеров неверной записи: | Несколько примеров неверной записи: | ||
| + | |||
| <sxh qsp> | <sxh qsp> | ||
| - | ! в этом случае, если условие не будет выполнено, | + | ! в этом случае, если условие не будет выполнено, |
| - | ! плеер проигнорирует только команду k1=34 | + | ! плеер проигнорирует только команду k1=34 |
| - | ! поскольку посчитает, что это однострочное условие | + | ! поскольку посчитает, что это однострочное условие |
| - | if abcd=3: k1=34 | + | if abcd=3: k1=34 |
| - | k2=35 & ! эта команда будет выполняться всегда | + | k2=35 & ! эта команда будет выполняться всегда |
| - | k3=36 & ! эта комнада будет выполняться всегда | + | k3=36 & ! эта комнада будет выполняться всегда |
| - | end & ! этот end будет проигнорирован | + | end & ! этот end будет проигнорирован |
| </sxh> | </sxh> | ||
| <sxh qsp> | <sxh qsp> | ||
| - | ! данная строка выведет ошибку "неизвестное действие" | + | ! данная строка выведет ошибку "неизвестное действие" |
| - | ! так как однострочные формы записи не должны оканчиваться end`ом | + | ! так как однострочные формы записи не должны оканчиваться end`ом |
| - | if abcd=3: k1=34 else k1=25 end | + | if abcd=3: k1=34 else k1=25 end |
| + | </sxh> | ||
| - | ! данная запись приведёт к ошибке: | + | Пример использования однострочных ''%%ELSEIF%%'' и ''%%ELSE%%'' (аналог ''%%CASE%%'' на **QSP**): |
| - | ! "Неверная запись однострочного оператора" | + | |
| - | if absd=3: | + | <sxh qsp> |
| - | k=34 | + | if 0: |
| - | else if absd=6: | + | elseif z = 0: y = x * 100 |
| - | k1=25 | + | elseif z = 1: y = x * 99 |
| - | end | + | elseif z = 2: y = x * 88 |
| + | elseif z = 3: y = x * 77 | ||
| + | else: y = x * 11 | ||
| + | end | ||
| </sxh> | </sxh> | ||
| - | ==== Особая форма записи конструкции условия с ELSEIF ==== | ||
| - | Оператор ветвления ''**ELSEIF**'' всегда используется только в многострочных конструкциях. Однако есть сокращённый вариант записи такой многострочной конструкции, который позволяет размещать команды в той же строке, что и ''**ELSEIF**''. | + | ===== Функции обработки условий ===== |
| - | **Обратите внимание!!!** Это не однострочная форма записи, это **особая форма многострочной записи**. Вот общий вид такой формы: | + | * ''%%IIF([#выр],[выр_да],[выр_нет])%%'' - возвращает значение выражения ''%%[выр_да]%%'', если ''%%[#выр]%%'' верно, иначе возвращает значение выражения ''%%[выр_нет]%%''. |
| + | * Эта функция в **QSP** является аналогом **тернарного оператора** в других языках программирования. | ||
| + | * Из выражений ''%%[выр_да]%%'' и ''%%[выр_нет]%%'' будет вычислено только одно, в зависимости от того, будет ли выполнено условие. | ||
| + | * Примеры: <sxh qsp> | ||
| + | !Модуль числа | ||
| + | abs_x=iif(x>0,x,-x) | ||
| + | !А следующая конструкция НЕ вызовет ошибку деления на ноль: | ||
| + | set x=0 y=iif(x=0,0,1/x) | ||
| + | ! типичное решение для вывода времени, чтобы не терять ноль на часах: | ||
| + | $iif(hour>9,$str(hour),"0"+$str(hour))+":"+$iif(minute>9,$str(minute),"0"+$str(minute)) | ||
| + | </sxh> | ||
| + | * Эквивалентность конструкций условия c оператором ''%%IF%%'' и функции ''%%IIF%%'': <sxh qsp> | ||
| + | if number mod 2 = 0: | ||
| + | *pl "Число чётное" | ||
| + | else | ||
| + | *pl "Число нечётное" | ||
| + | end | ||
| + | ! эквивалентно | ||
| + | *pl $iif(number mod 2 = 0,"Число чётное","Число не чётное") | ||
| + | </sxh> | ||
| + | |||
| + | ===== Проблема висячего ELSE ===== | ||
| + | |||
| + | Если вы часто пользуетесь однострочными конструкциями условий, вы неизбежно столкнётесь с "проблемой висячего ELSE". Это ситуация, когда невозможно однозначно трактовать, к какому ''IF'' относится ''ELSE''. Вот пример подобной неоднозначности: | ||
| <sxh qsp> | <sxh qsp> | ||
| - | IF [#условие 1]: | + | if first: if second: 'when true' else: 'when false' |
| - | {команды 1} | + | |
| - | ELSEIF [#условие 2]: {команды 2} | + | |
| - | ELSEIF [#условие 3]: {команды 3} | + | |
| - | ... | + | |
| - | ELSEIF [#условие N]: {команды N} | + | |
| - | ELSE: {команды} | + | |
| - | END | + | |
| </sxh> | </sxh> | ||
| - | Здесь обязательно команды ''{команды 1}'' после оператора ''**IF**'' должны идти в следующей строке после двоеточия, иначе плеер будет воспринимать строку с оператором ''**IF**'', как простую однострочную форму. А вот команды для ''**ELSEIF**'' и ''**ELSE**'' можно писать сразу в той же строке. Это очень удобно, когда надо организовать аналог ''**CASE**'' на **QSP**. | + | Сложно с ходу понять, к какому из ''IF'' — первому или второму — относится ''ELSE''. |
| - | Пример: | + | К счастью данная неоднозначность в QSP разрешается, как и во многих других языках программирования. ''ELSE'' всегда относится к ближайшему ''IF'' без ''ELSE''. То есть в данном случае ко второму. Вышеприведённая однострочная конструкция может быть представлена таким многострочным эквивалентом: |
| <sxh qsp> | <sxh qsp> | ||
| - | if x = 0: | + | if first: |
| - | y = x * 100 | + | if second: |
| - | elseif x = 1: y = x * 99 | + | 'when true' |
| - | elseif x = 2: y = x * 88 | + | else: |
| - | elseif x = 3: y = x * 77 | + | 'when false' |
| - | else: y = x * 11 | + | end |
| end | end | ||
| </sxh> | </sxh> | ||
| - | ===== Функции обработки условий ===== | + | Из этого правила вытекает возможность создавать вот такие конструкции, где у каждого ''IF'' есть свой ''ELSE'': |
| - | * ''**IIF(**[#выр]**,**[выр_да]**,**[выр_нет]**)**'' - возвращает значение выражения ''[выр_да]'', если ''[#выр]'' верно, иначе возвращает значение выражения ''[выр_нет]''. | + | <sxh qsp> |
| - | * Эта функция в **QSP** является аналогом **тернарного оператора** в других языках программирования. | + | if first: if second: 'when true' else: 'when false' else 'first false' |
| - | * Из выражений ''[выр_да]'' и ''[выр_нет]'' будет вычислено только одно, в зависимости от того, будет ли выполнено условие. | + | </sxh> |
| - | * Примеры:<sxh qsp> | + | |
| - | !Модуль числа | + | |
| - | abs_x=iif(x>0,x,-x) | + | |
| - | !А следующая конструкция НЕ вызовет ошибку деления на ноль: | + | А вот создать эквивалент такой многострочной конструкции в однострочной форме так просто не получится: |
| - | set x=0 | + | |
| - | y=iif(x=0,0,1/x) | + | |
| - | ! типичное решение для вывода времени, чтобы не терять ноль на часах: | + | <sxh qsp> |
| - | $iif(hour>9,$str(hour),"0"+$str(hour))+":"+$iif(minute>9,$str(minute),"0"+$str(minute)) | + | if first: |
| + | if second: | ||
| + | 'when true' | ||
| + | end | ||
| + | else: | ||
| + | 'when false' | ||
| + | end | ||
| </sxh> | </sxh> | ||
| - | * Эквивалентность конструкций условия с оператором ''**IF**'' и функции ''**IIF**'':<sxh qsp> | + | |
| - | if number mod 2 = 0: | + | Хотя, если //очень// нужно... |
| - | *pl "Число чётное" | + | |
| - | else | + | <sxh qsp> |
| - | *pl "Число нечётное" | + | if first: dynamic {if second:'when true'} else: 'when false' |
| - | end | + | if first: if second: 'when true' else: args=args else: 'when false' |
| - | ! эквивалентно | + | |
| - | *pl $iif(number mod 2 = 0,"Число чётное","Число не чётное") | + | |
| </sxh> | </sxh> | ||
| [[help:organizing|Вперёд: Пользовательские функции и процедуры]] | [[help:organizing|Вперёд: Пользовательские функции и процедуры]] | ||