УДОБНАЯ ЗАМЕНА ЦИКЛОВ "ПОКА..." НА БЕЙСИКЕ "КОРВЕТА"
При работе над программами часто бывает необходимо организовывать циклы с неизвестным количеством выполнений Из-за этой "неизвестности" не удается использовать наиболее быстрые и удобные "FOR ... NEXT", работающие внутри строки, и приходится вставлять выполняющиеся медленнее операторы проверки условия с командой перехода на строку "GOTO". Но в условиях Бейсика разбиение программы на большое число строк нецелесообразно, так как это увеличивает время работы компьютера. Оптимальным вариантом было бы использование специальных операторов "WHILE WEND", но в большинстве версий Бейсика, в том числе и на "Корвете", эти операторы не реализованы.
Я попытался заставить работать стандартный FOR-цикл как цикл "пока. ", не используя операторы проверки условия "IF ... THEN ... ELSE ...". Возможность достижения этого заключается в подборе определенных параметров при объявлении цикла, а иногда в преобразовании цикловой переменной.
Поэкспериментировав на контрольных примерах, мне удалось добиться выполнения цикла по условиям:
пока I%0 - 10 FOR I%=1 ТО 0 STEP-1 : INPUT I% : NEXT пока I% - 10 FOR I%=1 ТО 0 : INPUT I% : NEXT пока I%=0 - 10 FOR I%=0 ТО 1 : INPUT I% : I%=ABS(I%) : NEXT пока I%0 - 10 FOR I%=1 ТО 0 STEP 0 : INPUT I% ; NEXT
А вот пример привязки к конкретному числу:
пока I - 10 FOR I%=6 ТО 5 STEP-1 : INPUT I% : NEXT
Примечание. Возможно, подбор параметров не является наиболее совершенным вариантом. (Например, правильная работа циклов зависит от типа переменных. Так, при употреблении вещественного параметра I надо присвоить аргументу STEP минимальное значение). Поэтому цель примеров - показать читателям направление поиска решения этой задачи.
Для наглядной демонстрации, а заодно и для сравнения скоростей работы циклов, оформленных по "старому" и "новому" методам, можно использовать простую программу поиска какого-либо кода в ОЗУ с одновременным выводом содержимого памяти.
10 REM Вариант 1, стандартный
20 INPUT "Введи начальный адрес и предмет поиска:";Т,Х
30 I=PEEK(I):PRINT CHR$(I);:T=T+1:IF I THEN 30 : REM Сравнение очередного кода с искомым и вывод на экран
40 PRINT:PRINT HEX$(T-1):END : REM Вывод адреса найденного кода
10 REM Вариант 2, с оформлением цикла в виде 'пока I'
20 INPUT "Введи начальный адрес и предмет поиска:";Т,Х
30 FOR I=X ТО X STEP 0:I=PEEK(T):PRINT CHR$(I);:T=T+1:NEXT : REM Сравнение очередного кода с искомым и вывод на экран
40 PRINT:PRINT HEX$(T-1):END : REM Вывод адреса найденного кода
В обеих программах количество переменных одинаково, а различаются лишь строки под номером 30. В первом примере реализована команда ветвления, а во втором - исполняется цикл "FOR ... NEXT". Как можно заметить, конструкция программы становится неразветвленной, и это удобно не только для пользователя, но и для интерпретатора Бейсика.
При пробном запуске обеих программ для одинаковых начальных условий время выполнения для второго варианта оказалось приблизительно на 20% меньшим, чем для первого, а в среде интерпретатора Бейсика даже эти проценты можно считать достижением.
Кроме того, необязательно ограничиваться только приведенными примерами. При желании достаточно легко реализуются практически любые логические отношения: = и др. Так что стоит только понять общий принцип объявления циклов, и команда "WHILE ... WEND" появится в вашем Бейсике!
Примечание редактора
Внутренняя логика реализации оператора "FOR ... NEXT" уже сама по себе содержит оператор типа IF: при отработке оператора NEXT компьютер сначала вычитает величину шага цикла из цикловой переменной, а затем проверяет выполнение логического условия "больше"-"меньше". Для положительного приращения это можно выразить строкой:
IF (I+Step)=Kon_I THEN повтор цикла
Для отрицательного приращения - "с точностью до наоборот"
IF (I-Step)=Kon_I THEN повтор цикла
Наличие в этих условиях строгого или нестрогого логического условия, вообще говоря, зависит от версии транслятора Бейсика, но в большинстве случаев они такие, как в приведенных примерах.
Очевидно, что, искусственно подбирая значения переменных, задаваемых при вызове цикла (например, в FOR I=N_I ТО Kon_I STEP Step можно изменять значения N_I, Коп I и Step), и изменяя эти значения в теле цикла, можно заставить соответствующее оператору NEXT логическое условие стать "ложным" и вызвать выход из цикла только тогда, когда выполнится некоторое требуемое нам условие, т. е. реализовать цикл типа "пока".
Также очевидно, что все вышеприведенные рассуждения верны только в том случае, если требуемое для работы цикла "пока" логическое условие каким-либо образом связано с изменением цикловой переменной. Можно либо изменять "извне" значение самой цикловой переменной, как это сделано в приведенных автором примерах (значение цикловой переменной вводится с клавиатуры, считывается из памяти), либо вычислять внутри цикла новое значение цикловой переменной по значению другой, изменяемой нами переменной.
Предлагаемый автором статьи способ (хотя и несколько мудреный) позволяет повысить эффективность обработки программы. Кстати, это верно не только для Бейсика-"Корвет", но и для других версии на других компьютерах, например на БК-0010 01. Хотя на ней отсутствует возможность задания более чем одного оператора в строке, предлагаемый способ организации циклов будет полезен и там.
Недостатком данного способа является, во-первых, необходимость значительных усилий и немалой изобретательности, чтобы подобрать параметры цикла FOR наиболее оптимальным для какого-то конкретного случая образом (ведь всем понятно, что невозможно дать какое либо "стандартное" решение на все случаи жизни). А во-вторых, такой метод использования нарушает стандартную логику работы FOR-цикла, что требует особой внимательности при программировании. Поэтому данный способ организации циклов типа "пока" можно рекомендовать только опытным пользователям, хорошо знающим Бейсик, тогда как начинающим программистам лучше использовать стандартные FOR и IF.