Описание языка Basic. Правила работы 1.1. Общая характеристика алгоритмического языка Basic 1.2. Символы языка Basic 1.3. Простейшие конструкции языка 1.3.1. Числа 1.3.2. Переменные 1.3.3. Стандартные функции 1.3.4. Арифметические выражения 1.4. Основные операторы Basic 1.4.1. Оператор присваивания 1.4.2. Оператор безусловного перехода 1.4.3. Условные операторы 1.4.4. Операторы цикла 1.4.5. Оператор-комментарий 1.4.6. Операторы SТОР и ЕND 1.5. Операторы ввода/вывода 1.5.1. Операторы READ и DATA 1.5.2. Оператор RESTORE 1.5.3. Оператор INPUT 1.5.4. Оператор PRINT 1.5.5. Оператор PRINT USING 1.5.6. Использование функции ТАВ в операторе PRINT 1.6. Символьные переменные 1.7. Массивы 1.8. Подпрограммы 1.9. Файлы Алгоритмический язык Basic используется преимущественно в режиме диалога человека и ЭВМ. Этот язык ориентирован на решение различных задач вычислительного и невычислительного характера с небольшим объемом исходной информации. Название языка BASIC возникло от сокращения английских слов Beginner's All-purpose Symbolic Instruction Code (многоцелевой язык символических инструкций для начинающих). Следует отметить, что стандарта на язык Basic не существует и различные его модификации могут существенно отличаться друг от друга. В языке Basic существуют как средства для описания действий алгоритма, которые используются при составлений-программ, - операторы Basic, так и средства, которые служат для общения с ЭВМ. Последние имеют форму приказов для немедленного выполнения и называются командами. Основным режимом в Basic является программный режим, когда заранее составленная программа полностью вводится в ЭВМ и затем выполняется. Программа на Basic состоит из строк, которые могут иметь номер. В одной строке может содержаться один или несколько операторов, разделенных символом : (двоеточие). Обычно строки нумеруются, начиная с 10, с шагом 10. Номера строк используются в операторах передачи управления. При этом оператор, которому передается управление, должен быть первым в строке. Пример 1.1. Программа на языке Basic Программа 1.1 S=0 I=1 10 S=S+I I=I+1 IF I<=10 ТНЕN GOTO 10 PRINT S END Приведенная программа вычисляет сумму первых 10 натуральных чисел. Смысл каждого оператора и порядок их выполнения в программе очевидны. В результате выполнения программы будет вычислено значение S и оператором PRINT выведено на экран. 1.2. Символы языка Basic В языке Basic используются следующие символы: 1) 26 заглавных латинских букв от А до Z; 2) 10 цифр от 0 до 9; 3) знаки: . (точка), ; (точка с запятой), , (запятая), " (кавычки), ' (апостроф); 4) знаки арифметических операций: + (плюс), — (минус), * (знак умножения), / (знак деления), ^ (знак возведения в степень); 5) ( ) круглые скобки; 6) пробел; 7) знаки операций отношения <, >, = (сочетание <= используется вместо ≤, >= вместо ≥, < > вместо ≠); 8) знаки: $ (знак доллара), & (коммерческое “и” — амперсанд), @ (коммерческое “эт”), \ (обратный слэш), % (процент), # (номер), ?, !; 9) буквы русского алфавита от А до Я. 1.3. Простейшие конструкции языка 1.3.1. Числа Запись чисел на языке Basic близка к естественной. Числа, не имеющие дробной части, записываются привычным образом как последовательность цифр со знаком + или — (знак + можно опустить), например, +10, 12, —136. В числах, имеющих дробную часть, для отделения целой части от дробной используется точка, например, 1.2, - 0.6, или -.6 (0 целых можно опустить). Такая форма записи чисел называется основной. Допускается также запись чисел в форме с порядком. Например, число 0,00012, или эквивалентное ему 1,2.10-4, на языке Basic может быть записано как 1.2Е—4, где Е—4 используется вместо 10-4. Число 100000, или эквивалентное ему 105, может быть записано как 1Е5. Буква Е и следующее за ней целое число называются порядком. Целое число в записи порядка может содержать не более двух цифр. Порядку обязательно должно предшествовать число, записанное в основной форме. Сравните: 105, но 1Е5. Диапазон чисел, с которыми можно оперировать в Basic, составляет от 10-38 до 1038, количество значащих цифр числа не должно превышать шести, лишние цифры будут отброшены. Так, например, если вводится число 61232736, то оно будет представлено в ЭВМ только первыми шестью цифрами, т. е. как, например, 6.12327-107. При вводе числа 1000001 последняя 1 будет отброшена и число будет храниться в памяти как число 106. При вводе числа 0.00001648 оно будет храниться как 1.648« 10-5, при вводе числа 0.000001648974 оно будет храниться как число 1.64897« 10-6 и т. д. Под число, записанное в одной из приведенных выше форм (т. е. в основной форме или в форме с порядком), выделяется ячейка памяти длиной в 4 байта, и число хранится в ней в так называемой форме с плавающей запятой. Это — вещественные числа. В языке Basic существует еще одна форма записи чисел, когда к числу приписывается знак %. Такая форма записи используется только для целых чисел (чисел, не имеющих дробной части). Например, 1%,-34% и т.п. Целые числа могут принимать значения в диапазоне от -32768 до 32767. Под целое число, записанное в такой форме, выделяется ячейка памяти длиной 2 байта, и числа в ней представляются в так называемой форме с фиксированной запятой. Целые числа в Basic используются в основном из соображений экономии памяти. 1.3.2. Переменные Для обозначения вещественных переменных, т. е. переменных, значениями которых являются вещественные числа, в Basic используются имена, состоящие либо из одной буквы, либо из буквы и цифры. Например, А, А 2, С. В качестве букв используются прописные и строчные буквы латинского алфавита. Для целочисленных переменных, значениями которых являются целые числа, к имени добавляется знак %. Например, А%, А 2%, С%. Целочисленные и вещественные переменные должны принимать значения в пределах ограничений, указанных в разделе 1.3.1. Выход за пределы этих диапазонов вызывает сообщение об ошибке. 1.3.3. Стандартные функции При работе на ЭВМ имеется возможность использовать уже готовые (стандартные) программы, которые хранятся в памяти ЭВМ, для вычисления часто употребляемых функций. В таблице 1.1 приводятся стандартные функции, которые можно употреблять в Basic. Аргумент стандартной функции заключается в круглые скобки. В качестве аргумента можно употреблять любое арифметическое выражение (см. п. 1.4). Таблица 1.1. Стандартные функции Запись на языке Математическое определение Basic SIN(X) sin x Запись на языке Математическое Basic определение EXP (X) ex COS(X) cos x ABS(X) ATN(X) arctg x LOG(X) ln x SGN(X) LOG10(X) lg x SQR (X) [x]- наибольшее целое, не превосходящее x RND (X) Датчик случайных чисел INT(X) PI Число 3амечание. Аргумент функции RND можно опустить. Аргумент тригонометрической функции задается в радианах. Для перевода значения, заданного в градусах, в радианы можно использовать формулу знач. в рад.=знач. в град· /180. Для арктангенса значение угла находится в интервале (— /2; /2). Для получения других обратных тригонометрических функций можно использовать формулы аrcsin (x) = arctg (x/ ), arccos (x) = arctg( /x), arctg (x) =arctg (1/x). 1.3.4. Арифметические выражения Арифметические выражения соответствуют общепринятым алгебраическим выражениям. В арифметическое выражение могут входить числа, переменные, функции (стандартные или определяемые в программе), соединенные знаками арифметических операций. Число или переменная также является арифметическим выражением. Для обозначения арифметических операций используется знаки +, -, * (умножение), / (деление), ^ (возведение в степень). Примеры арифметических выражений Обычная запись Запись на Basic 4 4 a A a+4 A+4 2a 2*A A*B/C Если в арифметическом выражении имеется несколько различных арифметических операций, то порядок их выполнения задается правилами приоритета. Правила приоритета арифметических операций в Basic следующие: 1. ^ (возведение в степень). 2. *, / (умножение, деление). 3. +, - (сложение, вычитание). В арифметическом выражении могут употребляться круглые скобки. Если имеются скобки, то операции в скобках выполняются в первую очередь. Если в выражении несколько операций подряд имеют одинаковый приоритет, то они выполняются по порядку слева направо. Например, Х/У*Z соответствует (х/у)z, Х^У^2 соответствует (хy)z, Х/(У*Z) соответствует x/(yz) Замечание. В арифметическом выражении могут употребляться величины разных типов — целого и вещественного. Выполнение арифметических операций над величинами одного типа дает результат того же типа, сочетание целой величины и вещественной дает вещественный результат. 1.4. Основные операторы Basic 1.4.1. Оператор присваивания Оператор присваивания служит для присваивания переменной значения арифметического выражения и имеет следующий формат: LET v = ар. выр. (LET можно опустить), где v — переменная, которой присваивается значение. При выполнении оператора присваивания вычисляется выражение в правой части и присваивается переменной в левой части v. Примеры L=8 Р==Р+1 При употреблении оператора присваивания необходимо следить за тем, чтобы к моменту его выполнения переменные, входящие в выражение правой части, были определены (имели числовые значения). 1.4.2. Оператор безусловного перехода Формат оператора GO ТО N где N — номер строки. Этот оператор передает управление первому оператору в строке с номером N. Оператор GО ТО используется, в частности, при организации разветвлений для того, чтобы обойти операторы второй ветви, если выполнена первая. 1.4.3. Условные операторы Условные операторы служат для изменения порядка выполнения операторов в зависимости от какого-либо условия. Существуют два формата условного оператора. Первый формат условного оператора: IF условие ТНЕN блок_операторов_1 ELSE блок_операторов_2 END IF где: условие - любое выражение, значением которого является true (не нуль) или false (нуль); блок_операторов_1, блок_операторов_2 – один или более операторов, записанных на одной или более строк. Действие такого условного оператора заключается в следующем: если условие истинно, то выполняется первый блок операторов, после чего осуществляется переход к оператору, следующему за условным оператором. Если условие ложно, то выполняется второй блок операторов, после чего осуществляется переход к оператору, следующему за условным оператором. Второй формат условного оператора: IF условие ТНЕN операторы где: условие - любое выражение, значением которого является true (не нуль) или false (нуль); операторы – один или более операторов, записанных на одной строке и разделенных двоеточиями. Пример 1.2. Составить программу табулирования функции у==х ln х на отрезке [2; 3] с шагом 0, 1 (см. программу 1.2). Программа 10.2 Х=2 10 Y=X*LOG (X) PRINT X, Y Х=Х+.1 IF X<=3 GO TO 10 END 2 1.3862 2.1 1.55807 2.2 1.73461 2.3 1.91569 2.4 2.10112 2.5 2.29073 2.6 2.48433 2.7 2.68178 2.8 2.88293 2.9 3.08766 3 3.29583 В приведенной программе условный оператор используется для организации цикла. Если условие Х З выполняется, то осуществляется возврат в начало цикла к строке 10 для вычисления и печати значения функции в очередной точке. Пример 1.3. Составить программу для вычисления площади круга или площади квадрата в зависимости от введенного признака (см. программу 1.3). Программа 1.3 INPUT X, M IF M<0 THEN S=X*X PRINT"ПЛОШАДЬ КВАДРАТА";S ELSE S=PI*X*X PRINT "ПЛОЩАДЬ КРУГА";S END FI END Приведенная программа в зависимости от введенного значения М вычисляет площадь квадрата со стороной Х или площадь круга с радиусом X. Если М<0, то вычисляется и выводится площадь квадрата с помощью операторов, следующих за THEN. Если М О, то операторы, следующие за ТНЕN, не выполняются, а вычисляется и выводится площадь круга с помощью операторов, следующих за ELSE. 1.4.4. Операторы цикла Цикл является типичной структурой алгоритмов, реализуемых на ЭВМ. Для организации циклов в алгоритмических языках предусмотрены специальные операторы. В языке BASIC имеется несколько различных операторов цикла. Оператор FOR — NЕXТ. Формат оператора: FOR I = A1 TO A2 STEP A3 операторы NEXT i где: i — любая неиндексированная переменная — управляющая переменная цикла; A1, A2, A3 — начальное и конечное значения и шаг изменения управляющей переменной цикла — любые арифметические выражения. Если Аз=1, то конструкцию STEP A3 можно опустить. Операторы, расположенные между операторами FOR и NEXT, образуют тело цикла и выполняются многократно. Выполнение цикла, образованного операторами FOR — NЕХТ, заключается в следующем: переменной i присваивается начальное значение А1, и она сравнивается с конечным значением А2. Если при положительном шаге Аз удовлетворяется условие А1 Аз или при отрицательном шаге Аз удовлетворяется условие А1 А2, то выполняются операторы, расположенные между операторами FOR и NЕXТ, и по оператору NЕXТ осуществляется возврат к началу цикла. Значение i изменяется на шаг Аз, т. е. i=i+Аз, и снова проверяется условие. Если условие удовлетворяется, то тело цикла выполняется повторно. В противном случае происходит выход из цикла и переход к оператору, следующему за NЕХТ. Так как первая проверка условия выхода из цикла осуществляется до первого выполнения тела цикла, то возможна ситуация, когда тело цикла не будет выполнено ни разу. Пример 1.4. Составить программу для вычисления квадратов четных чисел от 2 до 10 (см. программу 1.4). Программа 1.4 FOR J=2 ТО 10 SТЕР 2 PRINT J, J*J NEXT J END Оператор DO - LOOP.Оператор имеет четыре формата: Первый формат оператора: DO WHILE условие операторы LOOP где: условие - любое выражение, значением которого является true (не ноль) или false (ноль); операторы – один или более операторов, записанных на одной строке или нескольких строках (тело цикла). Оператор цикла повторяет выполнение операторов, составляющих тело цикла, пока условие, записанное после слова WHILE истинно. Пример 1.5. Составить программу для вычисления квадратов четных чисел от 2 до 10 (см. программу 1.5). Программа 1.5 J=2 DO WHILE J<=10 PRINT J, J*J J=J+2 LOOP END Второй формат оператора: DO UNTIL условие операторы LOOP где: условие - любое выражение, значением которого является true (не нуль) или false (нуль); операторы – один или более операторов, записанных на одной строке или нескольких строках (тело цикла). Оператор цикла повторяет выполнение операторов, составляющих тело цикла, пока условие, записанное после слова UNTIL не станет истинным. Пример 1.6. Составить программу для вычисления квадратов четных чисел от 2 до 10 (см. программу 1.6). Программа 1.6 J=2 DO UNTIL J > 10 PRINT J, J*J J=J+2 LOOP END Третий формат оператора: DO операторы LOOP WHILE условие где: условие - любое выражение, значением которого является true (не нуль) или false (нуль); операторы – один или более операторов, записанных на одной строке или нескольких строках (тело цикла). Оператор цикла повторяет выполнение операторов, составляющих тело цикла, пока условие, записанное после слова WHILE истинно. Пример 1.7. Составить программу для вычисления квадратов четных чисел от 2 до 10 (см. программу 1.7). Программа 10.7 J=2 DO PRINT J, J*J J=J+2 LOOP WHILE J <= 10 END Четвертый формат оператора: DO операторы LOOP UNTIL условие где: условие - любое выражение, значением которого является true (не нуль) или false (нуль); операторы – один или более операторов, записанных на одной строке или нескольких строках (тело цикла). Оператор цикла повторяет выполнение операторов, составляющих тело цикла, пока условие, записанное после слова UNTIL не станет истинным. Пример 1.8. Составить программу для вычисления квадратов четных чисел от 2 до 10 (см. программу 1.8). Программа 10.8 J=2 DO PRINT J, J*J J=J+2 LOOP UNTIL J > 10 END 1.4.5. Оператор-комментарий Для облегчения восприятия и большей наглядности программы в нее целесообразно включать комментарии, которые поясняют работу отдельных частей программы, характеризуют используемые переменные и т. д. Для записи комментариев используется оператор REMARK (или сокращенно RЕМ). В этом операторе за служебным словом RЕМ могут быть записаны любые символы Basic. Все, что записано за словом RЕМ до конца строки, воспринимается как комментарий и при выполнении программы игнорируется. Вместо слова можно использовать символ ' (апостроф). В качестве примера дополним комментариями приведенную выше программу 1.2. Программа 1.9 REM ПРОГРАММА ТАБУЛИРОВАНИЯ ФУНКЦИИ Y=X*LOG (X) Х=2 ' НАЧАЛО ЦИКЛА ПО Х 10 Y=X*LOG (X) PRINT X, Y Х=Х+.1 IF X<=3 GO TO 10 ' КОНЕЦ ЦИКЛА END Включение операторов RЕМ в программу никак не влияет на ее выполнение, так что программа 1.9 будет выполняться точно так же, как программа 1.2. 1.4.6. Операторы SТОР и ЕND Оператор SТОР прекращает выполнение программы. При этом на экране появляется текст программы с подсвеченным оператором SТОР. Останов программы позволяет распечатать значения переменных, т.е. оператор SТОР является удобным средством для отладки программы. Выполнение программы может быть продолжено нажатием клавиши F5. Допускается использование в программе нескольких операторов SТОР. Использование оператора SТОР не является обязательным в Basic. Если оператор SТОР отсутствует, то выполнение программы продолжается до ее естественного завершения, т. е. до выполнения операторов, расположенных в строке с наибольшим номером. Оператор END указывает на физический конец программы. При выполнении оператора ЕND закрываются все открытые файлы и останавливается выполнение программы. Никакого сообщения на экран при этом не выводится. 1.5. Операторы ввода/вывода Операторы ввода служат для задания исходных данных при выполнении программы. Операторы вывода позволяют получить результаты выполнения программы. Ввод в Basic осуществляется одним из двух способов: использованием оператора INPUT или пары операторов READ, DATA. 1.5.1. Операторы READ и DATA Эти операторы в программе всегда присутствуют одновременно. Формат оператора READ имеет вид READ v1 [ , v2, …] где v1, v2, . . . — вводимые переменные (квадратные скобки обозначают необязательные параметры). Формат оператора DАТА имеет вид DАТА а1 [ , а2 , ...] где a1,a2, . . . — константы. Оператор DAТА содержит данные, которые при выполнении операторов RЕАD будут вводиться в переменные, перечисленные в списке ввода операторов RЕАD. Данные, подлежащие вводу, могут располагаться в одном операторе DАТА или в нескольких операторах DАТА, но в том порядке, в котором эти данные должны использоваться оператором (или операторами) RЕАD. Операторы DАТА могут располагаться в любом месте программы. В строке, содержащей оператор DАТА, не допускается использование других операторов. Перед выполнением программы все данные, содержащиеся в операторах DАТА, помещаются в специальную область памяти (область DАТА). Порядок расположения данных в области DАТА соответствует порядку следования различных операторов DАТА в программе, а для каждого оператора DАТА — порядку данных в этом операторе. Например, при наличии в одной программе следующих операторов: DАТА 10.6 DАТА 0.1,15,1.2 DАТА 5.1 данные в области DАТА будут расположены в такой последовательности: 10.6, 0.1, 15, 1.2, 5.1. При выполнении операторов READ данные из области DATA по очереди пересылаются в переменные, перечисленные в списке ввода операторов READ. Например, если в программе, содержащей приведенные выше операторы DАТА, имеются также операторы READ A, B, C READ D то после их выполнения переменные А, В, С, D будут иметь значения А=10.6, В=0.1,С=15, D=1.2. Если данных не хватает, то выводится сообщение об ошибке. 1.5.2. Оператор RESTORE Данные из области DАТА можно считывать повторно, используя оператор RESTORE. Формат оператора RESTORE [арифметическое выражение] Значение целой части арифметического выражения определяет номер данного, с которого начнется повторное считывание. Если арифметическое выражение отсутствует, осуществляется возврат к началу списка. Например, после выполнения группы операторов READ A, B, C, D DATA 10.6,0.1,15,1.2 RESTORE READ E,F будет А=10.6, В=0.1, С==15, D=1.2, Е=10.6, F=0.1. 1.5.3. Оператор INPUT При использовании оператора INPUT данные вводятся с клавиатуры во время выполнения программы. Формат оператора INPUT ["строка";] v1 [ , v2, ...] Где v1,v2, . . . - переменные; строка - строковая константа, которая выводится на экран, перед тем как пользователь начнет ввод данных. Этот элемент является необязательным. При выполнении этого оператора ЭВМ делает паузу, на экране высвечивается текст строки и "?" и ЭВМ ждет ввода данных. На клавиатуре дисплея необходимо набрать числа, подлежащие вводу, в порядке, задаваемом списком ввода. Если чисел несколько, то они отделяются друг от друга запятыми. После этого нажатием клавиши ENTER эти числа вводятся в ячейки памяти, выделенные для переменных, указанных в списке. Если данные не уместились в одной строке или их недостаточно, то на экране опять появляется "?" и система ждет ввода остальных чисел. После ввода значений всех переменных, перечисленных в списке, выполнение программы продолжается. Пример 1.9 INPUT A, B, C, D ? 10.6,0.1,15 ? 1.2 Пример 1.10 INPUT "Введите A и B";A, B Введите A и B? 10.6, 0.1, 15 Использование операторов READ, DATA целесообразно во время отладки программы, когда программа многократно выполняется с одними и теми же данными, вводимыми в этом случае один раз при вводе программы. Когда же отлаженная программа многократно выполняется с различными наборами данных, целесообразно использовать оператор INPUT. Использование операторов READ, DATA в этом случае требовало бы перед каждым выполнением программы с новыми данными замены операторов DATA, т. е. изменения текста программы. 1.5.4. Оператор PRINT Оператор PRINT используется для вывода на экран монитора или на принтер результатов вычислений. Формат оператора PRINT список Список вывода может содержать имена переменных, числа, арифметические выражения и тексты. Если список отсутствует, то при выполнении оператора PRINT просто осуществляется перевод строки. Тексты используются для печати всевозможных заголовков и пояснений. Текст заключается в кавычки или в апострофы и может содержать любые символы Basic. Если в списке вывода содержатся арифметические выражения, то они сначала вычисляются, а затем выводятся вычисленные значения. Для удобства восприятия выводимых результатов экран условно разделен на 5 зон, по 14 позиций каждая, и вывод каждого следующего данного осуществляется в следующую зону. Такая форма вывода обеспечивается использованием "," (запятой) в качестве разделителя в списке вывода. Например, при выполнении оператора PRINT "АРГУМЕНТ" , X , "ФУНКЦИЯ" , X^2 при Х=2 будет выведено Появление запятой всегда приводит к переходу к следующей зоне. Поэтому употребление двух запятых подряд или запятой в начале списка приводит к пропуску одной зоны. Например, при выполнении оператора PRINT ,"АРГУМЕНТ", X вывод начинается с 15-й позиции, т.е. при Х=2 будет напечатано АРГУМЕНТ 2 Такой способ вывода с использованием в качестве разделителя запятой называется выводом в зонном формате. После последнего элемента списка также может употребляться запятая. В этом случае при выполнении следующего оператора PRINT вывод элементов его списка будет осуществляться в следующей зоне (без перевода строки). Например, при выполнении операторов PRINT A, B, PRINT P при А=10.1, В=6.8, Р=190 будет выведено в одну строку 10.1 6.8 190 Отсутствие запятой после последнего элемента в списке приводит к переводу строки, так что следующий оператор PRINT начинает вывод с новой строки. Например, при выполнении операторов PRINT A, B PRINT P при тех же значениях А, В, Р будет выведено 10.1 190 6.8 Если в качестве разделителя используется ";", то вывод осуществляется в так называемом плотном формате, т. е. каждое следующее данное выводится после предыдущего через пробел. Например, оператор PRINT A; B; P приводит к следующей печати: 10.1 6.8 190 Такой способ вывода рекомендуется для более компактного вывода, когда выводится много данных, содержащих небольшое число значащих цифр. Замечание Результаты вычислений выводятся как десятичные числа (в основной форме), если они находятся в диапазоне от 0.01 до 999999. В противном случае числа выводятся в форме с порядком. При этом в стандартной форме вывода число перед порядком содержит обязательно один разряд (ненулевой) перед точкой и пять цифр в качестве дробной части. Под знак числа (кроме числа 0) предусматривается одна позиция, знак + не выводится. Например, при выполнении операторов A= 0.01: B=9.90000E-03: C=1.00000E+06 PRINT A, B, C на экран будет выведено 0.01 9.90000 E-03 1.00000 E 06 1.5.5. Оператор PRINT USING Дает возможность задать точный образ вывода отдельных элементов списка. Оператор PRINT USING имеет формат PRINT USING "строка"; список где строка содержит один или более символов форматирования. При выводе числовых значений предусматривается символ # для каждой выводимой цифры, а также знака числа. Если предполагается вывод с порядком, то для порядка предусматриваются символы ^^^^. Все остальные символы, включая пробелы, обозначают сами себя и выводятся без изменений. Для вывода числа, содержащего дробную часть, в формате задается столько символов #, сколько всего цифр требуется вывести, и точка для отделения цифр целой части от дробной. То есть использование формата позволяет отсечь при печати ненужные цифры. Результат при этом округляется. Примеры PRINT USING "#.## ##.#"; 5.629, -1.1 5.63 –1.1 PRINT USING "X=#.# F=####"; .151, 366.3 X=0.2 F= 366 Если в формате задан только один образ, то он может использоваться многократно для каждого элемента в списке вывода. Пример PRINT USING "##.##"; 10.1, -4.828 1.10 -4.83 Использование оператора PRINT USING при выводе массивов позволяет выводить массивы в удобной для восприятия форме, что иллюстрирует программа 1.10. Программа 1.10 DIM F2 (4,4) P= .5 FOR I=1 TO4 FOR J=1 TO 4 P=P+1 F2 (I, J)=P PRINT USING ''###.##"; F2 (I, J); NEXT J PRINT NEXT I END 1.50 2.50 3.50 4.50 5.50 6.50 7.50 8.50 9.50 10.50 11.50 12.50 13.50 14.50 15.50 16.50 Оператор PRINT в девятой строке осуществляет только возврат каретки перед выводом новой строки. Таким образом, оператор PRINT USING может обеспечить вывод результатов в любом желаемом формате. 1.5.6. Использование функции ТАВ в операторе PRINT Функция ТАВ может использоваться как один из элементов в списке вывода оператора PRINT. Она вызывает вывод следующего за ней элемента, начиная с позиции, номер которой задан как аргумент функции ТАВ. Общий вид функции ТАВ (арифметическое_выражение) Если значение арифметического выражения содержит дробную часть, то при определении позиции печати дробная часть отбрасывается. Аргумент должен быть заключен в диапазоне от 0 до 71 (по числу позиций строки экрана). Если аргумент функции ТАВ меньше текущей позиции строки, то эта функция игнорируется, печать осуществляется в следующую позицию. Например, при выполнении оператора PRINT ТАВ(20); 5 число 5 выводится в 21-ю позицию строки экрана (20-я позиция отводится под знак числа). При выполнении оператора PRINT TAB (5); 5; TAB (12); 89 в 6-ю позицию выводится 5, начиная с 13-й - 89. При выполнении оператора PRINT TAB (20);"*"; TAB (30); "0" в 20-ю позицию выводится *, в 30-ю - 0. При выполнении операторов X=20 PRINT TAB(X); "*" в 20-ю позицию выводится *. При выполнении операторов X=20 PRINT TAB (X);"*"; TAB (X-10);"0" * выведется в 20-ю позицию, 0 — в 10-ю позицию, но на следующей строке. Такой результат второй функции ТАВ объясняется тем, что она определяет позицию, меньшую текущей (при печати нельзя вернуться по строке назад). Функцию ТАВ можно использовать для вывода результатов в наглядной форме в виде графиков, таблиц, гистограмм. 1.6. Символьные переменные До сих пор мы имели дело только с переменными, значениями которых являются числа. Их называют числовыми переменными. В Basic имеется возможность использовать также переменные, значениями которых являются строки символов — так называемые символьные (или строковые) переменные. Символьные переменные обозначаются так же, как и числовые, т. е. буквой или буквой и цифрой с добавлением символа $ (знак доллара). Например, A$, В1$ и т. д. Длина символьной переменной (количество составляющих ее символов) может изменяться от 0 (пустая строка) до 255 символов. Задание значений символьных переменных осуществляется: 1. При помощи операторов ввода INPUT или READ,DATA. В операторе DATA строка символов заключается в кавычки. При использовании оператора INPUT значение символьной переменной при вводе должно заключаться в кавычки, если среди составляющих ее символов есть запятая (,). В остальных случаях использование кавычек не обязательно. 2. Оператором присваивания. Например, A$= "МОСКВА" Строка символов в правой части оператора задается в кавычках. Значения символьных величин, как и числовых, можно вывести при помощи операторов PRINT и PRINT USING. В списке вывода может быть указано имя символьной переменной или константа (строка символов), заключенная в кавычки или апострофы. Например, если A$= "ИВАНОВ", B$= "ПЕТРОВ", то при выполнении оператора PRINT A$; "И"; В$ будет выведено ИВАНОВ И ПЕТРОВ В операторе PRINT USING для вывода символьных величин используются следующие символы форматирования: & - выводится вся строка; ! - выводится только первый символ строки; \ \ - выводится n символов, где n равно количеству пробелов между символами \ (обратный слэш) плюс 2. Пример 10.11.. Ниже приведена программа, иллюстрирующая применение символов форматирования для вывода символьных данных. Программа 10.11 A$="ABCDEFGH" PRINT USING "&"; A$ PRINT USING "!"; A$ PRINT USING "\ \"; A$ END ABCDEFGH A ABCD В третьем операторе PRINT USING между символами \ введены два пробела, поэтому n=4, и на экран выводятся 4 символа строки A$. Символьные переменные можно сравнивать в условных операторах. Сравнение основано на том, что каждый символ в памяти ЭВМ представляется двоичным кодом и при сравнении символьных переменных происходит сравнение кодов составляющих их символов. Сравнение символьных переменных осуществляется посимвольно, начиная с первого символа. Если первые символы обеих переменных совпадают, то сравниваются вторые и т.д. Если длины (количество символов) сравниваемых переменных не совпадают, то меньшее дополняется пробелами (пробел является самым младшим символом). Например, при выполнении оператора IF A$ > B$ THEN PRINT A$ если A$="ИВАНОВ", B$="АНДРЕЕВ", условие выполняется и происходит вывод содержимого переменной A$. Операции и стандартные функции для символьных величин. Для символьных переменных определена одна операция: конкатенация (обозначается символом +). При выполнении этой операции две переменные объединяются в одну. Например, в результате выполнения операторов A$ ="МОС" : B$="КВА" C$ =A$ + B$ PRINT C$ на экране будет выведено МОСКВА Кроме операции конкатенации, для символьных переменных определены стандартные функции. • ASC(X$) переводит двоичный код символа в 10-ичное число. Функция применима только для переменной Х$, содержащей один символ. Например, X$="Q" PRINT ASC(X$) В результате будет напечатано 81 • LEN(X$) находит длину символьной переменной (т.е. количество составляющих её символов, включая конечные пробелы). Например, T$="МОСКВА" X=LEN(T$) В результате будет напечатано Х=6. • STR$(X) преобразует значение Х из числовой формы в символьную. • VAL(X$) преобразует последовательность символов, соответствующую записи числа на Basic, в число. Например, X$="126" S=1 P=S+VAL (X$) В результате выполнения этих операторов будет Р=127. Если последовательность символов не является числом, то выдается сообщение об ошибке. • LTRIM(Х$) возвращает строку Х$ с отброшенными ведущими пробелами. • RTRIM(Х$) возвращает строку Х$ с отброшенными конечными пробелами. Например, A$ = " BASIC " PRINT "*" + A$ + "*" PRINT "*" + LTRIM(A$) + "*" PRINT "*" + RTRIM(A$) + "*" В результате выполнения этих операторов будет выведено: * BASIC * *BASIC * * BASIC* • LEFT(Х$, N) возвращает первые N символов строки Х$. • RIGHT(Х$, N) возвращает последние N символов строки Х$. Например, A$ = "MICROSOFT BASIC" PRINT LEFT$(A$, 5) PRINT RIGHT$(A$, 5) В результате выполнения этих операторов будет выведено: *MICRO* *BASIC* • MID(Х$, N, [M]) возвращает последние M символов строки Х$, начиная с символа, позиция которого равна N. Если параметр M опущен, то функция возвращает все символы строки Х$, начиная с символа, позиция которого равна N. Например, A$ = "MICROSOFT BASIC" PRINT MID$(A$, 6, 4) В результате выполнения этих операторов будет выведено: SOFT 1.7. Массивы Переменные, которые мы использовали при составлении программ до сих пор, называются простыми переменными. Каждая простая переменная имеет имя, и под каждую такую переменную выделяется ячейка памяти, обращение к которой осуществляется по этому имени. Использование только простых переменных затрудняет или делает вообще невозможным решение многих важных задач. Рассмотрим пример. Предположим, что в памяти ЭВМ каким-то образом получена (может быть, просто введена) последовательность 10 чисел. Пусть требуется найти максимальное из введенных чисел, а затем разделить каждый элемент последовательности на максимальный элемент. При определении максимального элемента последовательности можно было бы вводить числа по очереди в одну и ту же ячейку памяти (т.е. использовать одну переменную), а максимальное из уже введенных чисел получать в другой переменной (см. рис. 1.11а). Однако при таком способе при поступлении нового числа из последовательности старое стирается (пропадает), и теперь, чтобы решить вторую часть задачи, нужно было бы второй раз вводить всю последовательность. Такой способ становится вообще неприемлемым, если члены последовательности вычисляются самой машиной каким-нибудь трудоемким способом Нужно, следовательно, каким-то образом запоминать значения, из которых выбирается максимальный элемент. Способ, который нам уже знаком,— использование переменных. Чтобы запомнить десять чисел, нужно десять различных переменных. Пусть это переменные A, B, C, D, E, F, G, H, S, T. Чтобы найти максимальное из этих значений (Р), нужно, положив вначале Р=А, сравнивать Р по очереди со всеми остальными переменным” и заменять Р. на новое значение, если значение очередной переменной больше Р (т. е. максимального из всех предшествующих). Программа, считая, что значения А, . . ., Т уже находятся в памяти, будет, например, иметь вид …………………………….. P=A IF B>P THEN P=B IF C>P THEN P=C IF D>P THEN P=D ……………………………… и т.д., пока не будут просмотрены все переменные. Изучая эту программу, можно видеть, что она состоит из повторяющихся операторов, отличающихся только именем использованной в них переменной. Если бы мы имели возможность указать какой-либо способ перехода к ячейке памяти, в которой находится значение следующей переменной, то в программе можно было бы написать только один подобный оператор. Такую возможность предоставляет использование массивов. Массивом называется упорядоченная последовательность величин, обозначаемая одним именем. Упорядоченность заключается в том, что элементы массива располагаются в последовательных ячейках памяти. Массив, вспоминая аналогию с ящиками, можно представить себе как несколько одинаковых ящиков, скрепленных вместе. На всю конструкцию как целое повешен один ярлык с именем массива (например, А). Все ящики в одной такой конструкции перенумерованы, начиная с 1. Ящики — это элементы массива. Номер ящика — значение индекса элемента массива (рис. 3.1). Чтобы получить доступ к нужному ящику, нужно указать имя массива и его индекс. Индекс записывается в круглых скобках после имени массива. Если нужно присвоить, например, значение 5 третьему элементу массива А, нужно написать A (3)=5 Рис. 1.1. При выполнении этого оператора будет найден массив А, отсчитан третий ящик (ячейка памяти) с начала и в него положено значение 5. Если нужно всем пяти элементам массива А присвоить значение 5, можно написать A (1)=5 A (2)=5 A (3)=5 A (4)=5 A (5)=5 Индекс может быть переменной, поэтому то же самое можно выполнить и другим способом: FOR I=1 TO 5 A (I)=5 NEXT I Мы, таким образом, имеем простой способ перехода от одного элемента массива к другому, изменяя индексы. Имя массива образуется так же, как имя переменной (буква или буква и цифра). В Basic массивы могут быть одномерные и двумерные. В двумерном массиве каждый элемент идентифицируется номером строки и номером столбца, на пересечении которых он расположен. Положение элемента в массиве определяется индексами: одним — для одномерных массивов и двумя — для двумерных. При записи элемента массива индекс (индексы) записывается в круглых скобках после имени массива. Если индексов два, то они разделяются запятой. В качестве индексов могут употребляться любые арифметические выражения. Если значение арифметического выражения содержит дробную часть, то при определении индекса она отбрасывается. Появление отрицательного значения индекса вызывает сообщение об ошибке. Переменные с индексами (элементы массива) могут употребляться в программе так же, как простые переменные (в левой части оператора присваивания, в арифметических выражениях и т. п.) Под массивы, так же как и под переменные, машина должна выделять память. Вспомним, что под переменную одна ячейка памяти выделялась, как только эти переменная первый раз встречалась в программе. Для массивов такой способ не годится. Ведь машина должна выделить память сразу под весь массив. А при первом появлении переменной с индексом в программе еще не известно, сколько ячеек памяти требуется выделить под весь массив. Поэтому машина должна получить эту информацию отдельно. Ей нужно сообщить, какие массивы будут использованы в программе и каков размер каждого массива. Эта информация задается в операторе описания массивов DIM. В операторе DIM указываются имя массива и в круглых скобках верхние границы изменения индексов, которые должны быть целыми положительными числами (нижняя граница фиксирована и равна 1). В Basic могут использоваться массивы как числовые, так и символьные. Например; оператор DIM A (3), B (4, 5), T$(12) описывает два числовых массива: А, состоящий из трех элементов (А (1), А (2), А(3)), и В, содержащий 4 строки и 5 столбцов, и символьный массив Т$, состоящий из 12 элементов. В соответствии с оператором DIM в памяти ЭВМ выделяется место для размещения этих массивов. Так, для массива А будут выделены три ячейки памяти, для массива В — двадцать ячеек, для массива Т$ — двенадцать ячеек памяти. Под двумерный массив выделяется линейный участок памяти, в котором массив располагается по строкам. Описание массива должно появляться в программе до первого обращения к элементам этого массива. Для улучшения структуры программы описание всех массивов рекомендуется давать в начале программы. Замечания. 1. В Basic допускается использование в одной программе одинаковых имен для обозначения простых переменных и массивов. Однако использование этой возможности на практике приводит к затруднению восприятия программы и может служить источником трудно обнаруживаемых ошибок. Поэтому настоятельно не рекомендуется использовать одинаковые имена для переменных и массивов. 2. В рассматриваемом варианте языка Basic фиксированное минимальное значение индексов равно 0 (а не 1, как указано выше), что является некоторым расширением возможностей языка по сравнению с используемым вариантом. Так, в соответствии с оператором DIM С (10), В (4, 5) машина всегда выделяет 11 и 30 ячеек памяти для размещения массивов С и В соответственно. Однако нумерация элементов с нуля для большинства задач неудобна и в дальнейшем изложении не используется. Все элементы массивов, имеющие индексы, равные нулю, будем далее игнорировать без дополнительных замечаний, т.е. будем считать, например, что в соответствии с описанием массивов DIM C (10), B (4, 5) массив С содержит десять элементов, массив В содержит четыре строки и пять столбцов. В Basic не определены операции с массивами. Поэтому любая обработка массивов, а также вводвывод массивов осуществляется поэлементно. Например, ввод одномерного массива А, содержащего 10 элементов, можно осуществить при помощи операторов DIM A (10) FOR I=1 TO 10 INPUT A (I) NEXT I Ввод двумерного массива В размером 4х5 можно осуществить при помощи операторов DIM B (4, 5) FOR I=1 TO 4 FOR J=1 TO 5 INPUT B (I, J) NEXT J NEXT I При одном выполнении оператора INPUT вводится один элемент массива (после набора на клавиатуре значения очередного элемента массива нужно нажать клавишу ENTER). Ввод двумерного массива в приведенной программе осуществляется по строкам. Вывод двумерных массивов для повышения наглядности рекомендуется осуществлять по строкам, начиная вывод каждой новой строки массива в новую строку экрана. Например, вывод массива В размером 4х5 можно осуществить при помощи операторов DIM B (4, 5) ……………………… FOR I=1 TO 4 FOR J=1 TO 5 PRINT B (I, J); NEXT J PRINT NEXT I Элементы одной строки будут выводиться в плотном формате. Оператор PRINT осуществляет возврат каретки перед печатью новой строки. Пример 1.12. В сессию 10 студентов одной группы сдали по 5 экзаменов. Результаты сессии представлены в виде матрицы М(10х5). Определить средний балл по каждому предмету. Результаты получить в виде одномерного массива С, содержащего 5 элементов. Решение. Просуммируем элементы каждого столбца матрицы М и, разделив на число студентов, поместим результат в соответствующий элемент массива С (см. программу 1.12). Для наглядности исходные данные задаются в программе в операторах DАТА. В одном операторе DАТА заданы оценки всех студентов по одному предмету, т. е. элементы одного столбца матрицы М. Ввод матрицы М осуществляется по столбцам. Программа 1.12 DIM M(10,5) ,C(5) DATA 5,4,5,3,4,3,3,3,4,4 DATA 5,5,3,5,3,4,5,4,5,4 DATA 3,4,5,3,4,5,3,3,3,3 DATA 4,4,4,4,4,5,4,4,3,3 DATA 4,3,3,3,5,4,3,3,5,5 FOR J=1 TO 5 FOR I=1 TO 10 READ M (I, J) NEXT I NEXT J FOR J=1 TO 5 S=0 FOR I=1 TO 10 S=S+M (I, J) NEXT I C(J)=S/10 NEXT J PRINT “ТАБЛИЦА СРЕДНИХ БАЛЛОВ ПО ЭКЗАМЕНАМ” FOR I=1 TO 5 PRINT C (I), NEXT I PRINT END ТАБЛИЦА СРЕДНИХ БАЛЛОВ ПО ЭКЗАМЕНАМ 3.8 4.3 3.6 3.9 3.8 1.8. Подпрограммы Когда некоторая совокупность действий должна выполняться в нескольких различных местах программы, то обычно нежелательно каждый раз повторять группу операторов, реализующих эти действия. Чтобы избежать повторений, указанную группу операторов можно записать в программе один раз и обращаться к ней, когда в этом возникает необходимость. Обособленную группу операторов, которую можно выполнять многократно, обращаясь к ней из различных мест программы, называют подпрограммой. Чтобы подпрограмма при обращении к ней выполнялась каждый раз с новыми данными, ее нужно составить в общем виде, а исходные данные для работы передавать в переменные подпрограммы перед обращением к ней. Если, например, в программе требуется, решить три квадратных уравнения с различными коэффициентами, то алгоритм нахождения корней квадратного уравнения целесообразно оформить в виде подпрограммы, используя для обозначения коэффициентов переменные. Перед каждым обращением к подпрограмме нужно задать этим переменным числовые значения, соответствующие коэффициентам решаемых уравнений. Использование подпрограмм уменьшает общее количество операторов в программе, и, следовательно, для размещения программы требуется меньше памяти. Время на выполнение программы при этом практически не изменяется. Подпрограммы обладают также некоторыми другими преимуществами. Использование подпрограмм улучшает структуру программы. Кроме того, облегчается отладка программы, так как работа каждой подпрограммы может быть проверена по отдельности. Многие подпрограммы имеют дополнительную ценность, поскольку ими может воспользоваться не только тот, кто написал подпрограмму, но и другие лица. Большинство машин располагает обширными библиотеками стандартных подпрограмм, которые существенно облегчают программирование реальных задач. В языке Basic подпрограммы могут быть оформлены как процедуры и функции. 1.8.1. Оператор DEF FN Помимо стандартных функций в программе можно определить и далее использовать другие (нестандартные) функции. Они особенно полезны, если повторяющиеся действия можно выразить в виде одного оператора, результатом исполнения которого является единственное значение. Такую однострочную функцию можно определить оператором DEF FN. Общий вид оператора DEF FNv(список_формальных_параметров)=арифметическое_выражение где v — заданное пользователем имя функции; список_формальных_параметров – последовательность идентификаторов, разделяемых запятыми. Значения формальных параметров передаются функции при ее вызове. арифметическое_выражение — формула, по которой вычисляется функция. Оператор DEF FN должен располагаться в программе до первого использования определяемой им функции. Вычисление функции, описанной оператором DEF FN, осуществляется при обращении к ней при помощи записи указателя функции: FNv(список_фактических_ параметров) где список_фактических_ параметров — арифметические выражения, заменяющие формальные параметры в арифметическом выражении правой части оператора DEF FN перед вычислением. Использование функции, заданной оператором DEF FN, аналогично использованию стандартных функций. Обращение к нестандартной функции (указатель функции) можно записать в арифметическом выражении, в списке вывода оператора PRINT и т. д., вообще везде, где требуется значение этой функции. Пример 1.13 DEF FNT(X)= X*X+A A=5 ……………….. P=FNT(3) Перед вычислением значения функции FNT формальный аргумент Х заменяется на фактический аргумент 3, указанный в обращении к функции, и с этим значением Х (Х=3) будет вычислено значение выражения Х*Х+А. В результате переменной Р будет присвоено значение 14. Пример 1.14 DEF FNV(X, Y)=X*X+Y*Y+A*A A=2: T=3.1: Z=8.6 ………………. P=0.5*SQR (FNV (SIN (T/PI), 2*Z)) В арифметическом выражении правой части оператора, вычисляющего значение переменной P, имеется обращение к функции FNV, используемой в качестве аргумента стандартной функции SQR. При вычислении функции FNV сначала будут вычислены арифметические выражения SIN(Т/РI) и 2*Z, значения которых заменят формальные аргументы Х и Y в арифметическом выражении, определяющем функцию FNV(X,Y), а затем вычислено значение этого арифметического выражения, т. е. значение функции FNV, которое заменит обращение к ней в выражении, являющемся аргументом функции SQR, т. е. фактически при вычислении значения Р будет выполнена следующая последовательность действий: X=SIN (T/PI) Y=2*Z V=X*X+Y*Y+A*A P=0.5*SQR (V) 1.8.2. Блочные функции Кроме однострочных функций Basic позволяет использовать функции, тело которых может быть образовано группой операторов. Ниже приведен формат описания блочной функции. FUNCTION name(список_формальных_ параметров) блок операторов name = выражение END FUNCTION где name — имя функции; список_формальных_параметров – последовательность имен переменных, разделяемых запятыми. Значения формальных параметров передаются функции при ее вызове. Список имеет следующий вид: переменная1 AS тип, переменная2 AS тип, …, переменнаяN AS тип выражение — формула, вычисляющая значение, возвращаемое функцией. Блочная функция возвращает только одно значение через имя функции. Вызов блочной функции осуществляется при помощи записи указателя функции в соответствии со следующим форматом: name(список_фактических_ параметров) где name — имя функции; список_фактических_ параметров - последовательность арифметических выражений, заменяющие формальные параметры при вызове функции. К спискам формальных и фактических параметров предъявляются следующие требования: 1. Количество элементов в обоих списках должно быть одинаковым. 2. Типы соответствующих элементов списка должны быть одинаковыми. Пример 1.15. Составить программу для вычисления числа сочетаний по формуле: Вычисление факториала оформить в виде функции (см. программу 10.13). Список переменных, используемых в главной программе. Исходные данные: n, m — целые неотрицательные числа, n m. Результат: Amount — число сочетаний из n по m. Вспомогательные переменные: a=n!, b=m!, c=(n-m)! Переменные в подпрограмме: k — переменная, факториал которой вычисляется в подпрограмме, f=k! вычисляется в подпрограмме, i — управляющая переменная цикла. Программа 10.13 DECLARE FUNCTION fct! (n AS INTEGER) DIM n AS INTEGER, a AS INTEGER, b AS INTEGER DIM m AS INTEGER, c AS INTEGER, amount AS INTEGER INPUT "Введите N, M"; n, m PRINT "N="; n, "M="; m a = fct(n) PRINT "N!="; a b = fct(m) PRINT "M!="; bc = fct(n - m) PRINT "(N-M)!="; c amount = a / (b * c) PRINT Число сочетаний="; amount END FUNCTION fct (k AS INTEGER) DIM i AS INTEGER, f AS INTEGER f=1 FOR i = 1 TO k f=f*i NEXT fct = f END FUNCTION Пояснения к программе. Оператор DECLARE вводить не нужно, поскольку Basic генерирует его автоматически при сохранении программы. Функция fct вызывается три раза в операторах присваивания. Перед обращением к функции в переменную k, используемую в подпрограмме, передаются соответственно значения n, m, n - m, для которых вычисляется факториал. Переменные a, b и с служат для запоминания вычисленных значений n!, m! и (n-m)!. Пример 1.16. Сформировать с помощью функции RND двумерный массив А(5,6) и определить значения минимальных элементов каждой строки массива. Значения минимальных элементов определить с помощью функции (см. программу 1.14). Программа 1.14 DECLARE FUNCTION MinMatr! (a(), k AS INTEGER, m AS INTEGER) ' Использование функции CLS DIM m AS INTEGER, i AS INTEGER n = 5: m = 6 DIM a(n, m) ' Формирование исходной матрицы RANDOMIZE TIMER FOR i = 1 TO n FOR j = 1 TO m a(i, j) = INT(RND * 10) NEXT j NEXT i ' Вывод исходной матрицы PRINT "Исходная матрица A" FOR i = 1 TO n FOR j = 1 TO m PRINT a(i, j); NEXT j PRINT NEXT i ' Определение минимальных элементов строк матрицы FOR i = 1 TO n mina = MinMatr(a(), i, m) PRINT "Строка="; i, "Min="; mina NEXT i END FUNCTION MinMatr (a(), k AS INTEGER, m AS INTEGER) 'Функция возвращает минимальный элемент в k-й строке' DIM min AS INTEGER, j AS INTEGER min = a(k, 1) FOR j = 1 TO m IF a(k, j) < min THEN min = a(k, j) NEXT j MinMatr = min END FUNCTION Пояснения к программе. Оператор DECLARE вводить не нужно, поскольку Basic генерирует его автоматически при сохранении программы. Функция MinMatr имеет три формальных параметра. Первый параметр используется для передачи в функцию значений исходного массива. Параметр k передает в функцию номер строки, в которой нужно определить минимальный элемент. В третьем параметре передается количество столбцов массива. Результат работы функции возвращается как значение указателя функции MinMatr. В основной программе функция MinMatr вызывается в цикле, параметром которого служит номер строки массива. 1.8.3. Процедуры В то время как функции возвращают только одно значение через имя функции, процедуры способны возвращать любое число значений. Они обладают возможностью использовать и модифицировать любую переменную или любой массив, которые доступны программе. Ниже приведен формат описания процедуры. SUB name(список_формальных_ параметров) блок операторов END SUB где name — имя процедуры; список_формальных_параметров – последовательность имен переменных, разделяемых запятыми. Значения формальных параметров передаются процедуре при ее вызове. Список имеет следующий вид: переменная1 AS тип, переменная2 AS тип, …, переменнаяN AS тип Вызов процедуры осуществляется при помощи оператора CALL в соответствии со следующим форматом: CALL name(список_фактических_ параметров) где name — имя процедуры; список_фактических_ параметров - последовательность арифметических выражений, заменяющие формальные параметры при вызове процедуры. К спискам формальных и фактических параметров предъявляются следующие требования: 1. Количество элементов в обоих списках должно быть одинаковым. 2. Типы соответствующих элементов списка должны быть одинаковыми. Пример 10.17. Составить программу для вычисления числа сочетаний по формуле: Вычисление факториала оформить в виде процедуры (см. программу 1.15). Список переменных, используемых в главной программе. Исходные данные: n, m — целые неотрицательные числа, n m. Результат: Amount — число сочетаний из n по m. Вспомогательные переменные: a=n!, b=m!, c=(n-m)! Переменные в процедуре: k — переменная, факториал которой вычисляется в процедуре, f=k! вычисляется в процедуре, i — управляющая переменная цикла. Программа 1.15 DECLARE SUB fct (k AS INTEGER, f AS INTEGER) DIM n AS INTEGER, a AS INTEGER, b AS INTEGER DIM m AS INTEGER, c AS INTEGER, amount AS INTEGER INPUT "Введите N, M"; n, m PRINT "N="; n, "M="; m CALL fct(n, a) PRINT "N!="; a CALL fct(m, b) PRINT "M!="; b CALL fct(n - m, c) PRINT "(N-M)!="; c amount = a / (b * c) PRINT "Число сочетаний="; amount END SUB fct (k AS INTEGER, f AS INTEGER) DIM i AS INTEGER f=1 FOR i = 1 TO k f=f*i NEXT END SUB Пояснения к программе. Оператор DECLARE вводить не нужно, поскольку Basic генерирует его автоматически при сохранении программы. Процедура fct вызывается три раза с помощью оператора CALL. При вызове процедуре с помощью первого формального параметра передаются значения n, m, n - m, для которых вычисляется факториал. Второй формальный параметр процедуры используется для передачи результата работы процедуры в главную программу. Пример 1.18. Сформировать с помощью функции RND двумерный массив А(5,6) и определить значения минимальных элементов каждой строки массива. Значения минимальных элементов определить с помощью процедуры (см. программу 3.8). Программа 1.16 DECLARE SUB MinMatr (a(), k AS INTEGER, m AS INTEGER, min AS INTEGER) ' Использование процедуры CLS RANDOMIZE TIMER DIM i AS INTEGER, m AS INTEGER, Mina AS INTEGER n = 5: m = 6 DIM a(n, m) ' Формирование исходной матрицы FOR i = 1 TO n FOR j = 1 TO m a(i, j) = INT(RND * 10) NEXT j NEXT i ' Вывод исходной матрицы PRINT "Исходная матрица A" FOR i = 1 TO n FOR j = 1 TO m PRINT a(i, j); NEXT j PRINT NEXT i ' Определение минимальных элементов строк матрицы FOR i = 1 TO n CALL MinMatr(a(), i, m, Mina) PRINT "Строка="; i, "Min="; Mina NEXT i END SUB MinMatr (a(), k AS INTEGER, m AS INTEGER, min AS INTEGER) 'Процедура вычисляет минимальный элемент в k строке' DIM j AS INTEGER min = a(k, 1) FOR j = 1 TO m IF a(k, j) < min THEN min = a(k, j) NEXT j END SUB Пояснения к программе. Оператор DECLARE вводить не нужно, поскольку Basic генерирует его автоматически при сохранении программы. Процедура MinMatr имеет четыре формальных параметра. Первый параметр используется для передачи в функцию значений исходного массива. Параметр k передает в функцию номер строки, в которой нужно определить минимальный элемент. В третьем параметре передается количество столбцов массива. Результат работы функции возвращается с помощью четвертого параметра Min. В основной программе процедура MinMatr вызывается оператором CALL в цикле, параметром которого служит номер строки массива. 1.9. Работа с файлами данных Наборы данных целесообразно хранить на диске в тех случаях, когда • должны обрабатываться большие объемы данных, которые целиком не помещаются в оперативной памяти; в этом случае данные предварительно записываются на диск и небольшими порциями вызываются в оперативную память для обработки; • одни и те же данные используют различные программы; тогда каждая программа может получать данные считыванием их с диска; • целесообразно сохранить результаты выполнения программы, например, для последующего использования другими программами. Для идентификации и удобства дальнейшей работы наборам данных присваиваются имена. Набор данных с именем называется файлом. Для работы с файлами данных (формирования файла или считывания из файла) файл нужно объявить в программе ("открыть" файл). Открытие файла данных осуществляется при помощи оператора ОРЕN имя FOR режим AS FILE #n где имя – имя файла, которое может включать имя диска и путь к файлу; режим – режим использования файла; INPUT – указывается при считывании данных из файла, OUTPUT - указывается при записи данных в файл; n – номер файла (число в диапазоне от 1 до 255), который идентифицирует файл во время его открытия. Закрытие файла данных должно осуществляться после окончания работы с ним при помощи оператора CLOSE #n где n — номер открытого файла; если номер файла опущен, то оператор закрывает все открытые в данный момент файлы. В Basic имеется возможность работать с файлами данных последовательного и прямого доступа. Далее рассматриваются только файлы последовательного доступа. Файл последовательного доступа характеризуется тем, что порядок следования данных в нем определяется последовательностью, в которой данные записываются на диск. Считывание из файла последовательного доступа возможно только в том же порядке, в котором данные хранятся в этом файле. Пересылка данных в файл последовательного доступа осуществляется при помощи оператора PRINT #n, список Считывание из файла последовательного доступа осуществляется при помощи оператора INPUT #n, список где n — номер открытого файла. Список здесь имеет тот же смысл, что и для операторов PRINT и INPUT, изученных ранее. Данные, передаваемые в файл при помощи одного оператора PRINT #n , называются записью. Таким образом сформированный файл состоит из последовательности записей. Считывание из файла также осуществляется записями, т. е. при пересылке данных в следующий элемент списка оператора INPUT #n выбирается следующая запись. Это необходимо учитывать при формировании файла. Рекомендуется, как правило, при одном выполнении оператора PRINT #n записывать в файл одно данное, т. е. список оператора PRINT #n должен содержать только один элемент. После окончания пересылки данных в файл последовательного доступа и выполнения оператора CLOSE на диске формируется признак конца файла. Пример 1.19. Составим программу для формирования файла последовательного доступа. Имя файла вводится пользователем. В этот файл записывается строка текста, которая затем считывается из файла и выводится на экран (см. программу 1.17). Программа 1.17 INPUT "Введите имя файла: "; n$ OPEN n$ FOR OUTPUT AS #1 PRINT #1, "Эта строка сохранена в файле." CLOSE #1 OPEN n$ FOR INPUT AS #1 INPUT #1, a$ PRINT "Считано из файла: "; a$ CLOSE #1 END Считано из файла: Эта строка сохранена в файле. Пояснения к программе. Первый оператор программы запрашивает имя файла, который затем открывается для записи данных во втором операторе. Оператор PRINT записывает в открытый файл строку текста, после чего файл с номером 1 закрывается. В пятой строке программы созданный ранее файл открывается для чтения и с помощью оператора INPUT из файла считывается запись, которая помещается в строковую переменную a$. Затем значение переменной a$ выводится на экран. Пример 1.20. В качестве примера составим программу для записи двумерного массива в файл последовательного доступа. Файл a:\matr.dat создается на диске А:. В этот файл записываются значения элементов матрицы, генерируемые с помощью функции RND(). Одновременно значения элементов матрицы выводятся на экран (см. программу 1.18). Программа 1.18 OPEN "a:\matr.dat" FOR OUTPUT AS #1 PRINT "Введите размер матрицы" INPUT n FOR i = 1 TO n FOR j = 1 TO n a = INT(RND(i) * 10) PRINT a; PRINT #1, a; NEXT j PRINT PRINT #1, NEXT i CLOSE #1 END Пояснения к программе. Первый оператор программы открывает файл с номером 1 для записи данных. Затем пользователь вводит размер матрицы, значения элементов которой генерируются с помощью функции RND(). Оператор PRINT #1, а; записывает в открытый файл элемент матрицы. Матрица записывается в файл и выводится на экран по строкам. В конце программы файл, открытый для записи закрывается. Если при считывании из файла количество данных в нем заранее не известно, то для окончания считывания можно использовать функцию EOF(#n), n — номер файла. Пример 1.21. В качестве примера составим программу для считывания данных из файла последовательного доступа и записи их двумерный массив (см. программу 1.19). Файл a:\matr.dat был создан на диске А: в предыдущем примере. В этот файл были записаны значения элементов матрицы. Программа 1.19 OPEN "a:\matr.dat" FOR INPUT AS #1 INPUT n DIM a(n, n) FOR i = 1 TO n FOR j = 1 TO n INPUT #1, a(i, j) PRINT a(i, j); IF EOF(1) THEN 100 NEXT j PRINT NEXT i 100 : CLOSE #1 END Пояснения к программе. Первый оператор программы открывает файл с номером 1 для считывания данных. Затем пользователь вводит размер матрицы, значения элементов которой необходимо считать из файла. Оператор INPUT #1, a (i, j) считывает очередное значение из файла и записывает его в очередной элемент двумерного массива. Если достигнут конец файла, т.е. считано последнее значение из файла, то функция EOF (1) возвратит значение TRUE (ИСТИНА) и управление будет передано оператору с меткой 100, находящемуся за пределами цикла. Одновременно матрица записывается выводится на экран по строкам. В конце программы файл, открытый для записи, закрывается.