Формат команды [L]LIST: [L]LIST [n1][-n2] где: [L]LIST("Line printer LIST out","list"-"список") - служебное слово; n1,n2 - целые константы (0≤n1,n2≤65529) или десятичная точка("."). Эта команда, которая может быть оператором программы,выводит текст про- граммы, находящейся в данный момент в памяти. Если указано служебное сло- во LIST, то вывод происходит на э к р а н дисплея; если используется слу- жебное слово LLIST, то текст отсылается на печатающее устройство (п р и н- т е р) и печатается на бумаге. Если параметры не указаны, то выводится на экран (или принтер) вся про- грамма. Если после служебного слова [L]LIST задан номер программной стро- ки, то выводится только строка с указанным номером. Тире до или после это- го номера означает, что будет выведен весь текст программы соответственно до или после строки с этим номером.Два номера программных строк, разделен- ные тире, указывают,что должны быть выведены только строки программы с но- мерами, находящимися внутри данного диапазона. Чтобы указать на "текущий" номер программной строки,Вы можете использо- вать символ "." вместо параметров n1 и n2. Клавиша "STOP" используется для организации паузы в процессе вывода текста программы на экран дисплея или принтер. Для продолжения вывода про- граммы следует нажать клавишу "STOP" вторично. П р и м е р. NEW ─────────── Ok 200 DEFSTR A-C 150 DEFDBL C-K 100 DEFSNG K-M LIST . 100 DEFSNG K-M Оk LIST -175 100 DEFSNG K-M 150 DEFDBL C-K Оk II.4. ЛИНЕЙНЫЕ ПРОГРАММЫ Напомним,что в школьном алгоритмическом языке л и н е й н ы м и назы- вались алгоритмы, состоящие из серии команд присваивания. Для программирования линейных алгоритмов практически необходимы знания правил употребления только трех операторов: оператора ввода данных, опера- тора присваивания, оператора вывода данных. Эти операторы,естественно,при- меняются и в более сложных программах. Л и н е й н о й будем называть программу, в которой все операторы,на- чиная с первого,выполняются последовательно один за другим,причем выполня- ется каждый оператор (притом, только о д и н раз). II.4.1. О п е р а т о р п р и с в а и в а н и я LET Чтобы выпить из чаши, нужно ее наполнить! Восточная мудрость Структура оператора присваивания: [LET] п е р е м е н н а я = в ы р а ж е н и е , где: LET ("пусть") - служебное слово; п е р е м е н н а я - имя новой или существующей переменной или имя элемента массива, или имя псевдопеременной (см. раздел I.7.5.); "=" - знак присваивания; в ы р а ж е н и е - либо строковое, либо арифметическое выражение того же типа, что и п е р е м е н н а я, либо логическое выражение. В результате выполнения оператора присваивания п е р е м е н н а я (имя которой стоит слева от знака присваивания) приобретает новое значе- ние (являющееся значением в ы р а ж е н и я, стоящего справа от знака присваивания). MSX-BASIC - язык арифметики,а не алгебры: оператор LET при- сваивает переменной слева именно ч и с л о , а никак не алгебраическое выражение, стоящее справа! П р и м е р ы: 1) NEW ───────────── Ok 10 LET A1=10.04 20 END Данная программа позволяет присвоить переменной A1 начальное значение 10.04 (инициализировать ее). Проверим это. Сначала выполним программу: run Ok А теперь... print A1 10.04 Ok 2) NEW 3) NEW 4) NEW Ok Ok Ok 10 P1=3.14159 10 LET X=5.4 10 LET Z=5>=-1 20 P2=INT(P1/0.001+.5)*0.001 20 LET Y=FIX(X+.5) 20 END run 30 END run Ok run Ok print P1 Ok print Z 3.14159 print Y -1 Ok 5 Ok print P2 Ok 3.142 Ok Обратите внимание на то, что оператор,расположенный в программной стро- ке 20 примера 2, позволил о к р у г л и т ь значение переменной X. Два следующих оператора присваивания позволят вычислить старший и млад- ший байты целого числа A%: H%=A%\256:L%=A%MOD256 Отметим, что служебное слово LET в записи оператора присваивания можно опускать, что не меняет сущности оператора присваивания; так, например, идентичны следующие фрагменты программ: 20 LET M%=A%-INT(A%/B%)*B% и 20 M%=A%-INT(A%/B%)*B% Хотелось бы отметить,что начинающих программистов часто ставит в тупик, например, оператор вида: X = X + 1 В математике такая запись бессмысленна.Но по определению оператора при- сваивания такая запись вполне законна: вначале вычисляется значение выра- жения, стоящего в правой части (значение переменной X, существовавшее до момента выполнения этого оператора ( старое значение ), увеличивается на единицу), и полученное значение присваивается той же переменной X. Еще один пример применения оператора присваивания и операции вычисле- ния остатка для организации циклических изменений значений целых числовых переменных: X%=(X%+1)MOD256 Этот оператор позволяет увеличивать X% с 0 до 255. Когда значение X% будет равно 255, оператор присваивания тут же установит значение X% рав- ным 0. Еще раз обратите внимание, что символ "=" здесь отнюдь не совпадает по смыслу с символом равенства "=" в математике,несмотря на одинаковую форму и обманчивое сходное использование! Оператор присваивания обладает следующими о с о б е н н о с т я м и . Если переменной некоторого типа присваивается значение выражения друго- го типа, то тип выражения преобразуется к типу переменной. Попытка присво- ить значение строкового выражения числовой переменной или наоборот, вызо- вет сообщение об ошибке "Type mismatch" ("Н е с о о т в е т с т в и е т и п о в"). П р и м е р ы: 1) Оk 2) Ok ───────────── А%=23.42:print A% A="нельзя!":print A 23 Type mismatch Ok Ok 3) Ok 4) Ok 5) Ok a%=123456:? a% b!=123456.78:? b! d!=123456789:?d! Overflow 123457 123457000 Ok Ok Ok Если переменной целого типа присваивается значение выражения, вычислен- ное с одинарной или двойной точностью,то у значения выражения отбрасывает- ся дробная часть. 6) Оk 7) Ok C%=55.88:print C% C%=-1.97:? C% 55 -1 Ok Ok Если переменной двойной точности присваивается значение выражения, вы- численное с одинарной точностью, то только первые 6 цифр значения выраже- ния являются точными (напомним, что одинарная точность обеспечивает 6 зна- чащих цифр результата), т.е. 8 разрядов,добавляемых к значению,всегда рав- ны нулю. Некоторые компьютеры при этом добавляют цепочку непредсказуемых разрядов,из-за чего следует быть очень осторожным,чтобы в вычислениях,тре- бующих высокой точности, не возникали абсурдные результаты! 8) Оk A!=SQR(2):B=A!:PRINT A!,B 1.41421 1.41421 Ok 9) Ok A=TAN(2*ATN(1)):B!=TAN(2*ATN(1)):C=B!:? A;B!;C -15915494309189 -15915500000000 -15915500000000 Ok Перед отбрасыванием "лишних" значащих цифр производится о к р у г л е- н и е: анализируется старшая из отбрасываемых цифр и если она больше или равна 5, то младшая из оставшихся цифр увеличивается на 1. При вычислении значения выражения все операнды во встречающихся опера- циях и результат вычислений приводятся к одной и той же степени точности - к наиболее высокой. Учтите, что наивысшая степень точности - у операндов двойной точности, далее следуют в порядке убывания степеней точности: операнды с одинарной точностью и целые операнды. П р и м е р: Оk ─────────── D=6/7!:print D .85714285714286 Ok Десятичная константа 6 - двойной точности, константа 7 имеет тип одина- рная точность, а переменная D по умолчанию имеет тип двойная точность, по- этому арифметическое действие было выполнено с двойной точностью, и полу- ченный результат имеет также тип двойная точность. П р и м е р: Оk ─────────── D!=6/7:print D! .857143 Ok Арифметическое действие было выполнено с двойной точностью (оба операн- да по умолчанию имеют двойную точность!), результат присваивается перемен- ной одинарной точности,поэтому перед присваиванием выполнено округление и выведено значение переменной D одинарной точности. Оператор присваивания -наиболее употребительный во всех языках програм- мирования. В BASIC он часто используется также в качестве оператора ввода данных. Наконец,заметим,что в языках программирования легко сказать "з а п о м- н и", но сложно говорить "з а б у д ь"! II.4.2. О п е р а т о р SWAP Оператор SWAP используется для обмена значениями двух переменных и за- писывается в виде: SWAP α,β или SWAP γ,δ где: SWAP ("swap"-"обмен") - служебное слово; α,β - имена числовых переменных или имена элементов числового масси- ва (числовых массивов); γ,δ - имена строковых переменных или имена элементов строкового мас- сива (строковых массивов). Этот оператор позволяет осуществлять обмен значениями двух переменных одинаковых типов. Обычно, не зная оператора SWAP, програмисты используют для обмена значениями следующие приемы: TEMP=A:A=B:B=TEMP или A=A+B:B=A-B:A=A-B . Оператор SWAP позволяет выполнить обмен за одну операцию, т.е. со значи- тельным увеличением скорости и экономией места. Заметим, что к двум переменным можно применить оператор SWAP только в том случае, если предварительно им присвоены определенные значения! П р и м е р ы: 1) А=3:B=2:SWAP A,B:PRINT A;B ───────────── 2 3 Ok 2) C$="мама":D$="папа":SWAP C$,D$:PRINT C$;D$ папамама Ok Еще раз отметим, что переменные, заданные в качестве аргументов, долж- ны быть одного и того же типа, причем в отличие от других операторов, это требование более жесткое, так, например, нельзя обменивать значения пере- менных одинарной и двойной точности. Нарушение этого требования приводит к сообщению об ошибке: "Type mismatch" ("Н е с о о т в е т с т в и е т и п о в"). Наиболее эффектно применение оператора SWAP при сортировке массивов (см. пример в разделе III.4)! II.4.3. О п е р а т о р к о м м е н т а р и я REM Оператор REM имеет следующий синтаксис: REM Т е к с т к о м м е н т а р и я После служебного слова REM и до конца данной программной строки может следовать любой текст. Оператор REM не оказывает никакого влияния на ход выполнения программы; единственное его назначение - сделать программу бо- лее ясной и понятной. Весь текст строки программы, следующий за служебным словом REM, воспринимается интерпретатором как некоторое поясняющее заме- чание. Поэтому, если комментарий является частью программной строки,содер- жащей несколько операторов, то соответствующий оператор REM должен быть п о с л е д н и м оператором данной программной строки. Например, 10 Z=10.1:REM Начальное значение присвоено! Другой способ включения в текст программы комментариев - это использо- вание а п о с т р о ф а ("'"). Все символы, стоящие в программной строке за апострофом, рассматриваются как поясняющее сообщение. Если комментарий стоит в конце строки, содержащей несколько операторов, а вместо слова REM используется апостроф,то двоеточие перед апострофом не ставится (за исклю- чением оператора DATA). Например, 95 D=P*Q 'Уточнение коэффициента D! После завершения написания и о т л а д к и программы Вы можете соз- дать вариант Вашей программы только для счета, исключив все комментарии. Это приведет к уменьшению времени выполнения Вашей программы и умeньшению объема используемой оперативной памяти. Забегая вперед, отметим, что под о т л а д к о й п р о г р а м м по- нимается обычно один из этапов решения,во время которого с помощью компью- тера происходит обнаружение и исправление ошибок, имеющихся в программе;в ходе отладки программист хочет добиться определеной степени уверенности в том, что его программа соответствует своему назначению и не делает того, для чего она не предназначена. Многие начинающие программисты обычно пренебрегают комментариями или приписывают сообщения, не содержашие полезной информации, к готовой про- грамме. Обычно они утверждают, что и без комментариев знают все,что в ней происходит. Это, конечно так, но через несколько недель обязательно что- нибудь да забудется! Начинающие программисты считают, что им никогда не придется модифицировать уже отлаженную программу. Это грубая ошибка. Необ- ходимость в неожиданных добавлениях и изменениях готовой программы может привести к хаосу и недоразумениям,когда, к примеру, забыто назначение не- которого оператора, либо неизвестно, зачем в данном месте программы обну- ляется некоторая переменная. Как же избежать подобной ситуации ? Ответ прост. Вам следует всегда очень подробно документировать текст Вашей программы еще во время ее соз- дания. В этом заключается один из способов застраховать себя от непредска- зуемых заранее неприятностей. Существует т р и у р о в н я документирования, которых следует при- держиваться. П е р в ы й у р о в е н ь - это общее описание программы в начальном блоке комментариев. Он включает в себя даты создания и последующих модифи- каций программы, номер ее версии, имя автора.Здесь же указываются аргумен- ты и результаты работы алгоритма, по которому составлена программа. Кроме того, следует описать используемый алгоритм шаг за шагом. Эта часть может быть использована в качестве введения для неискушенного пользователя,разъ- ясняющая ему, что делает Ваша программа и как ею пользоваться. Более того многие программисты считают, что перед непосредственным про- граммированием необходимо написать инструкцию по использованию будущей программы! В т о р о й у р о в е н ь состоит в документировании каждого бло- ка программы (либо каждой подпрограммы) (см. раздел IV.4). В каждом блоке программы следует отмечать комментарием его начало, где упомянуть, что он соответствует определенным шагам, описанным ранее в алгоритме. Начало лю- бой подпрограммы следует снабжать комментариями, объясняющими,что же все- таки она делает. Наконец, т р е т и й у р о в е н ь документирования - построчный. Не- обходимо пояснять любую необычную комбинацию операторов или любой "хитро- умный" прием программирования. Комментируйте так, как будто бы Вы отвечаете на вопросы читателя.Очень эффективный метод состоит в том, чтобы сначала написать текст программы без комментариев, а затем посмотреть на него глазами читателя.Если окажет- ся, что у читателя в некоторой точке программы может возникнуть вопрос, следует вставить содержательный комментарий с ответом на него. Физически "выдвигайте" все комментарии из текста собственно программы. При печати комментарии следует смещать вправо от текста программы так,что- бы читатель мог просматривать программу, не прерываемую комментариями. Прокомментируйте все переменные. Понимание данных - ключ к пониманию программы. Каждое предложение, объявляющее некоторую переменную,должно со- провождаться комментарием, поясняющим смысл этой переменной. Если Вы будете придерживаться этих рекомендаций, то время, которое Вы потратите на написание подробных комментариев с лихвой окупится тем, что через полгода (!) Вы будете понимать свою собственную программу! Кроме того, для программиста, который первый раз видит чужую програм- му и хочет в ней разобраться, комментарии и примечания на обычном челове- ческом языке, поясняющие логику, структуру, конкретные операторы програм- мы, играют неоценимую роль. Хорошие,понятные комментарии - это элемент не только культуры программирования, но и культуры общения,показатель отноше- ния автора программы к коллегам и потенциальным потребителям программы в целом. II.4.4. О п е р а т о р в ы в о д а д а н н ы х PRINT в п р о с т е й ш е м с л у ч а е ...мало толку в программе, которая только и делает, что секретничает сама с собой. Л.Хэнкок, М.Кригер Оператор вывода данных на экран дисплея в простейшем случае состоит из служебного слова PRINT ("to print"-"печатать"), за которым следует спи- сок выражений любого типа, значения которых должны быть выведены на экран дисплея. Служебное слово PRINT для сокращения записи может быть заменено символом "?". Выражения в составе списка разделяются в простейшем случае символами- р а з д е л и т е л я м и : либо запятой,либо точкой с запятой,что опреде- ляет взаимное расположение выводимых значений на экране дисплея (впрочем, символы-разделители можно иногда опускать; см. ниже пример 11). Оператор PRINT в простейшем случае выполняет а в т о м а т и ч е с- к о е ф о р м а т и р о в а н и е , при котором распределение элемен- тов данных на экране осуществляется соответственно символам-разделителям, расположенным между ними. Если выражения в списке оператора PRINT разделены з а п я т о й , то указанный символ служит интерпретатору сигналом разделить дисплейную стро- ку на зоны, по 14 позиций каждая (ясно, что количество полных зон может быть не больше двух в случае 40-символьного экрана!) и выводить значения выражений последовательно с первой позиции каждой зоны,т.е. обеспечить вы- вод значений в з о н н о м формате (отметим,что позиции дисплейной стро- ки нумеруются, начиная с нуля!). Если на экран выводятся значения более двух выражений, то значение тре- тьего и всех последующих выражений отображаются в начале тех же зон, но с новой дисплейной строки. Если данные занимают не более 13 позиций, то сле- дующая зона располагается прямо за концом данных без вывода пробелов. П р и м е р ы: 1) NEW NEW ───────────── Оk Ok 10 X=2:Y=X^2 10 X=2 20 PRINT X,Y или 20 PRINT X,X^2 30 END 30 END run run ·2············▲4 ·2············▲4 Ok │ Ok │ 15-я позиция (начало второй зоны) В том месте дисплейной строки, где надо обратить Ваше внимание на нали- чие символа пробел (" "), мы будем использовать в тексте символ "·"! Если же данные занимают более 13-ти позиций, то следующая зона пропус- кается. 2) PRINT 1234567.34,"TIMER" 3) ? 123456.789101124,"TIMER" ·1234567.34···TIMER ·123456.78910112 Ok ▲ TIMER ▲ │ Ok │ 15-я позиция 16-я позиция При наличии т о ч к и с з а п я т о й в качестве символа-разделите- ля выражений в списке оператора PRINT, компьютер выводит значения в п л о т н о м формате (значения выражений отделены друг от друга о д - н и м пробелом). Оператор PRINT без параметров вызывает переход в начало первой зоны следующей дисплейной строки. 4) NEW 5) NEW Ok Ok 10 X=3 10 X=3 20 PRINT X;X^3 20 PRINT X:PRINT:PRINT X^3 25 PRINT X;-X^4 30 END 30 END run run ·3 ·3··27 ·3·-81 ·27 Ok Ok Если в списке встречаются лишние запятые, соответствующие пустым эле- ментам данных,то пропускается соответствующее число зон печати. Например, для вывода на экран дисплея данных не с первой, а со второй зоны используйте оператор: PRINT ,A,B . Поговорим теперь о формате вывода числовых данных.Прежде всего выводит- ся знак числа. Если число отрицательное, выводится знак "-", в случае по- ложительного числа выводится пробел.Более того,пробел также помещается за каждым выведенным числовым значением. Если возможно, интерпретатор "избегает" индикации на экране всех деся- тичных позиций выводимого значения и выводит числа в форме с плавающей точкой со стандартной мантиссой (это происходит, когда целая часть выводи- мого числа содержит не менее п я т н а д ц а т и значащих цифр или ког- да число по модулю ≤ 0.001), например: 6) Ok 7) Ok PRINT 12345678910112.1434 PRINT 123456789101121.434 ·12345678910112 ·1.2345678910112E+14 Ok Ok Заметим,что каждый оператор PRINT выводит информацию на экран дисплея, начиная с первой позиции новой строки. Однако, имеется возможность продол- жить вывод с помощью оператора PRINT на той же строке, где он закончился при выполнении предшествующего оператора PRINT. Для этого достаточно по- ставить в конце списка выражений, содержащегося в предшествующем операто- ре PRINT, символ-разделитель "," или ";". 8) NEW 9) NEW 10) NEW Ok Ok Ok 10 X=3 10 X=3 10 ?"YAMAHA"; 20 PRINT X;X^3; 20 PRINT X;X^3, 20 PRINT:PRINT"!" 25 PRINT X;X^4 25 PRINT X;X^4 run 30 END 30 END YAMAHA run run ! ·3··27··3··81 ·3··27········▲3··81 Ok Ok Ok │ 15-я позиция С помощью оператора PRINT можно (и должно),используя строковую констан- ту, (последовательность символов, заключенную в кавычки), организовать бо- лее информативный, к р а с и в ы й вывод результатов работы программы. П р и м е р 11. ────────────── NEW или NEW Ok Ok 10 X=5.08:Y=15.5 10 X=5.08:Y=15.5 20 PRINT "РЕЗУЛЬТАТЫ" 20 PRINT "РЕЗУЛЬТАТЫ" 30 PRINT "X = ";X,"Y = ";Y 30 PRINT "X = "X"Y = "Y 40 END 40 END run run РЕЗУЛЬТАТЫ РЕЗУЛЬТАТЫ X·=··5.08·····Y·=··15.5 X·=··5.08·Y·=··15.5 Ok ▲ Ok │ 15-я позиция (начало второй зоны) Опишем интересные д о п о л н и т е л ь н ы е возможности оператора ?: а) существует возможность начать вывод значения некоторого выражения с точно указанной позиции дисплейной строки (с позиции N). Для этого доста- точно поместить в операторе PRINT перед этим выражением функцию TAB(α) где: TAB("to TABulate"-"табулировать") - служебное слово; α - арифметическое выражение, целая часть значения которого лежит на отрезке [0,255]; обозначим N=INT(α). Функция TAB(α) сообщает оператору PRINT,что от текущей позиции курсора на дисплейной строке и до позиции с указанным номером N включительно надо вывести пробелы (к у р с о р - специальный знак "█",отмечающий одну из по- зиций ввода на экране дисплея). Если значение N м е н ь ш е номера пози- ции текущего положения курсора, то перемещения не происходит. Напомним Вам, что номера позиций курсора на дисплейной 40-символьной строке следующие: 0, 1, 2,..., 39. П р и м е р 12. NEW ────────────── Ok 10 V=1:S=3.5 20 PRINT TAB(3);"V=";V;TAB(11);"S=";S 30 END run ··▲V=·1···▲S=·3.5 │ │ │ 11-я позиция 3-я позиция Ok П р и м е р 13. NEW ────────────── Ok 10 V=1:INPUT M,N 'Ширина экрана - 39 позиций! 20 PRINT TAB(M);"V=";V;TAB(N);"V=";V run ? 1,5 ·V=·1·V=·1 Ok ... run run ? 2,6 ? 4,43 ··V=·1·V=·1 ····V=·1···...··· Ok ····V=·1 ▲ run Ok │ ? 1,7 ... 39-я позиция ·V=·1··V=·1 Ok Забегая вперед, отметим, что номер позиции текущего положения курсора на дисплейной строке можно получить, используя встроенную функцию POS(0) (см. раздел V.3). Кроме того, функция TAB(n) позволяет программисту получить удобное раз- мещение колонок выводимых результатов, если вывод по зонам, задаваемым за- пятой (через 14 позиций), слишком широк. П р и м е р 14. NEW ────────────── Ok 10 INPUT X,A,B,C 20 PRINT A;TAB(X);B;TAB(2*X);C'Символы";"можно опускать! run run ? 5,2,2,2 ? 3,2,2,2 ·2··▲·2··▲·2 ·2··2··2 │ │ Ok 5-я позиция│ 10-я позиция (2·5) Ok b) В операторе (команде) PRINT часто используется функция SPC(α) где: SPC ("SPaCe"-"пространство") - служебное слово; α - арифметическое выражение, целая часть значения которого лежит на отрезке [0,255]. Обозначим N - целую часть значения арифметического выражения α (N∈ [0,255]). Тогда функция SPC(α) выведет N пробелов, начиная с текущей пози- ции курсора. П р и м е р 15. NEW ────────────── Ok 10 INPUT Z,U,V,W 20 PRINT U;SPC(Z);V;SPC(Z);W run ? 3,2,2,2 ▲2▲···▲2▲···▲2 │ │ │ │ │ пробелы для знака │ │ обязательные пробелы после числа Запомните, что встроенные функции TAB() и SPC() допустимы т о л ь к о в операторе (команде) PRINT!