[an error occurred while processing this directive]
.сс
.шп6
18 Дополнительные функции, операторы и переменные
.шп0
В этой главе мы встретим функции POS, VPOS, COUNT, ABS и SGN. Мы также научимся использовать операторы DIV и MOD и контролировать печатью с помощью WIDTH.
.шп14
18.1 Положение на экране (POS и VPOS)
.шп0
Положение курсора на экране можно считывать с помощью тех же чисел, которые используются для TAB(). Числа, идущие горизонтально, начинаются с 0 и в зависимости от режима могут доходить до 20, 31, 41, 63 или 83. Числа, идущие вниз, начинаются с 0 и в зависимости от режима могут доходить до 16 или 31.
.шп1
POS является функцией, которая возвращает число текущего положения курсора по горизонтали. Это положение, в котором печать будет продолжаться.
VROS является функцией, которая возвращает число текущего положения курсора по вертикали. Это положение, в котором печать будет проолжаться.
.шп0
Компьютер может сказать нам о позиции курсора с помощью POS для положения по горизонтали и VPOS для положения по вертикали.
Введите (в прямом режиме)
print pos
и
print vpos
POS - нуль, потому что когда нажимается клавиша ВВОД, POSition(позиция), на которой будет продолжаться печать - это начало следующей строки.
Невозможно передвигать курсор и тем самым присваивать величины POS и VPOS. Они являются функциями, которые возвращают величины. Попытка присвоить величину вызовет сообщение об ошибке Not allowed (не разрешено). Попробуйте, если хотите.
.шп14
18.2 Примеры POS и VPOS
.шп0
Введите следующую программу, чтобы посмотреть действие POS.
10 mode := 6 20 repeat 30 print "*"; 40 untill ros = 19
Запустите.
А сейчас добавьте
15 print tab(20);
Запустите и просмотрите.
После строки 15 POS возвращает величину больше 19, поэтом у печать продолжается и на следующей строке и заставляет POS вернут величину 0. Печать прекращается, когда POS возвращает величину 19.
Уничтожьте строку 15 и измените строку 40 на
40 untill vpos = 19
Просмотрите и запустите.
Сейчас введите
15 print tab(0,20);
Просмотрите и запустите.
Чтобы остановить печать, необходимо нажать клавишу ВВОД. После строки 15 VPOS возвращает величину 20 и затем увеличивается с каждой новой строкой, пока не достигнет 24 (в нижней части экрана). Курсор не возвращается в верхнюю часть экрана. Верхняя строка экрана потеряна, все другие строки передвигаются вверх и в нижней части появляется новая строка.
Уничтожьте строку 15.
.шп14
18.3 Возврат каретки и перевод строки
.шп0
В те дни, когда программы компьютера печатались на механических клавиатурах, термин "возврат каретки" вошел в обиход как команда, которая возвращала каретку на начало строки. "Перевод строки" вызывал перемещение бумаги вверх на одну строку. И возврат каретки и перевод строки были нужны, когда требовалась новая строка.
В настоящее время, когда мы вводим данные с электронных клавиатур, соединенных с телеэкранами, клавиша ВВОД действует так же, как и возврат каретки и перевод строки.
Когда команда PRINT кончается без запятой или точки с запятой, возврат каретки используется для того, чтобы следующая позиция печати перешла на новую строку. Если печать не вмещается на одной строке и переходит на другую, это не означает возврата каретки.
Эти термины возврат каретки и перевод строки используются и сейчас. Они также употребляются при описании работы принтера.
.шп14
18.4 COUNT (счет).
.шп0
Компьютер следит за тем, сколько было напечатано символов, начиная с последнего "перевода каретки".
.шп1
COUNT - это функция, которая возвращает число символов, напечатанных с момента возврата каретки.
.шп0
Когда печать переполняет одну строку и переходит на другую, COUNT не возвращается на нуль, а продолжает счет.
Измените строку 40 на
40 UNTIL COUNT = 100
Просмотрите и запустите.
Измените строку 40 на
40 UNTIL COUNT = 255
и еще раз запустите.
Это максимальное число, которое может вернуть COUNT.
.шп14
18.5 WHIDTH (Ширина)
.шп0
Добавьте строку
15 Width := 15
и запустите программу.
.шп1
WIDTH - это системная переменная, которую можно использовать для того, чтобы контролировать количество символов, напечатанных перед тем, как возвратом каретки и переводом строки курсор перемещается на новую строку (в этом случае COUNT возвращается на нуль).
.шп0
В строке 15 измените WIDTH на 8 и запустите программу.
Нажмите РЕД и просмотрите.
Забавно, но не очень помогает при просмотре.
Введите прямую команду WIDTH := 0
и снова просмотрите.
Это опущенная (или нормальная) величина для WIDTH.
.шп14
18.6 ABS
.шп1
ABS - это функция, которая возвращает "абсолютную" величину числа, т.е. его значение независимо от знака, напр. ABS(3) и ABS(-3) оба возвращают 3.
.шп0
Введите new и
10 mode := 6 20 for j := -11 to 11 30 print j,abs(j) 40 next j
Просмотрите и запустите программу.
Измените 30 на
30 PRINT TAB( ABS(j));"Acornsoft COMAL"
Просмотрите и запустите снова.
Если вы хотите переместить форму к центру экрана измените строку 30 на
30 PRINT TAB( 5 + ABS(j));"Acornsoft COMAL"
.шп14
18.7 SGN
.шп1
SGN - это функция, которая возвращает 1,0, или -1 для обозначения положительного, нулевого или отрицательного аргумента (величины).
.шп0
Измените строку 30 на
30 PRINT j,SGN(J)
Просмотрите и запустите.
.шп14
18.8 DIV
.шп0
DIV - это бинарный оператор, который имеет такой же эффект, что и деление, только работает он с целыми числами и производит тоже целое число.
Целое число, которое необходимо разделить ставится перед DIV, а целое число, на которое нужно делить - за DIV.
6 DIV 3 дает 2, но и 7 DIV 3 дает 2, потому что DIV возвращает результат только в целых числах.
Если мы применяем DIV с десятичными величинами, то в Комале дробная часть игнорируется, например: 6.2 DIV 3 возвращает 2.
Если мы используем как делитель с DIV нецелое число, то его дробная часть игнорируется, например: 6 DIV 2.9 возвращает 3.
.шп1
DIV возвращает целое число, которое получается в результате деления целого числа на целое.
.шп0
Измените 30 на
30 PRINT j,j DIV 3// Notice sraces
Пробелы нужны, чтобы ключевое слово DIV не воспринималось как часть переменной jdiv3.
Просмотрите и запустите.
.шп14
18.9 MOD
.шп0
MOD является двоичным оператором, который возвращает целый остаток при делении двух целых чисел. Если MOD используется с нецелыми числами, то в Комале дробные части отбрасываются и возвращается целый остаток деления, например:
24 MOD 6 возвращает 0 24 MOD 5 возвращает 4 6 MOD 6 возвращает 0 24.5 MOD 5 возвращает 4 5 MOD 6 возвращает 5 24 MOD 5.2 возвращает 4
.шп1
MOD возвращает целый остаток от деления одного целого числа на другое.
.шп0
Измените 30 на
30 PRINT j,j DIV 3, j MOD 3
Просмотрите и запустите.
MOD в Комале возвращает остаток, когда деление происходит целое число раз. -7 MOD 3 производит -1.
.шп14
18.10 Предшествование MOD и DIV
.шп1
MOD и DIV обладают более высоким предшествованием, чем + и - , но такое же, что и * или /.
.шп0
Введите
PRINT 2*3 MOD 3
что произведит величину, данную (2*5) MOD 3, т.е. 1.
Введите
PRINT 2 + 5 DIV 3
что поизводит величину, данную 2 + (5 DIV 3), т.е. 3.
Будьте осторожны с MOD и DIV. Могут понадобиться скобки. Полная таблица предшествования приведена в секции 40.6.
.шп14
18.11 Реверсирование процесса
.шп0
Для любого определенного набора целых чисел, MOD и DIV соотносятся. Например:
59 = 8 * (59 DIV 8) + 59 MOD 8 77 = 6 * (77 DIV 6) + 77 MOD 6 a# = b# *(a# DIV b#) + a# MOD b#
.шп14
18.12 Итоговые упражнения
.шп0
Как вы думаете, что произведут следующие команды?
1. PRINT ABS(-5) 2. PRINT 15 DIV 4 3. PRINT SGN(15) 4. PRINT 15 MOD 3 5. PRINT -SGN(-15) 6. PRINT ABS(-9 DIV 4) 7. PRINT 15.5 MOD 4 8. PRINT 16.8 DIV 2.6 9. PRINT 4 * 10 DIV 4 + 10 MOD 4
Какие программы произведут слеующие группы чисел с помощью функций ABS, SGN, DIV, MOD и INT ?
10. 5 11. 1 12. 3
4 1 3 3 0 3 2 -1 2 1 -1 2 0 -1 2 1 -1 1 2 1 3 1
13. 4 14. 2 15 2
3 1 2 2 0 1 1 2 1 0 1 0 4 0 0 3 -1 -1 2 -2 -1 1 0 -2 0 -1 -2
Ответы приведены в главе 43.
.шп14
18.13 Выводы
.шп0
1. POS и VPOS - функции, которые возвращают позиции курсора на экране по горизонтали и вертикали. Но ими невозможно контролировать курсор.
2. COUNT - функция, которая возвращает число символов, напечатанных после возврата каретки.
3. WIDTH - системная переменная, которая может использоваться для числа символов, которые будут напечатаны до возврата каретки и перевода строки.
4. ABS - функция, которая возвращает абсолютную величину, т.е. величину без знака.
5. SGN - функция, возвращающая 1,0 или -1 для указания на положительный, нулевой или отрицательный аргумент.
6. DIV - оператор, который возвращает целое число, которое показывает сколько раз одно целое число может быть разделено другим.
7. MOD - оператор, который возвращает целый остаток от деления одного целого числа на другое.
8. MOD и DIV обладают более высоким предшествованием, чем + или -, и такое же предшесвование, что и * или /.
.сс
.шп6
19 Массивы
.шп0
В этой секции мы изучим как использовать массив для хранения набора одинаковых элементов и как устанавливать размеры массива.
.шп14
19.1 Введение
.шп0
Представьте себе взвод солдат на занятиях по строевой подготовке. Инструктор видит неправильный подъем руки и выкрикивает команду.
"Руку прямее: вторая шеренга, номер три!"
Команда выкрикивается всему взводу, но команда прямо адресована только одному члену взвода, положение которого определяется шеренгой и позицией в шеренге.
Мы можем применять похожий метод для обращения с наборами информации в компьютере. Мы можем использовать одну переменную как "взвод" величин, а затем с помощью чисел, которые указывают ряд и позицию можем идентифицировать отдельные элементы.
Компьютерный "взвод" называется "массивом", а числа, которые определяют отдельные элементы называются "индексами".
Например, если мы хотим вести запись фигур на шахматной доске, то piece¤(5,4) может представить название фигуры, находящейся в пятом ряду, на четвертой позиции. 5 - это первый индекс, а 4 - второй индекс.
.шп1
Массив - это коллекция величин под одним, определяющим ее именем, отдельные элементы которой определяются индексами.
.шп14
19.2 Размеры
.шп0
Массиву не нужно иметь два индекса, он может иметь и один, а в Комале их число может доходить до восьми. Каждый индекс представляет размер массива.
total(9) можно присвоить в качестве, скажем, общего количества баллов, набранных кандидатом номер 9. total( ) является одноразмерным массивом.
item¤(3,2,12) можно отнести к имени компонента, который хранится в блоке 12 уровня 2 шкафа 3. item¤ - это трехразмерный массив.
.шп14
19.3 Запоминание массивов.
.шп0
Память компьютера конечно же не восьмиразмерная. Как же она справляется с запоминанием элементов массива?
Если мы вернемся к мысли о "взводе", то мы можем понять, что происходит. Вообразите, что инструктор хочет отвести свой взвод для занятий в класс. Он не сможет ввести всех в класс строем, потому что в дверь может пройти только один человек. Однако инструктор может ввести взвод, пропустив сначала первую шеренгу, затем среднюю и, наконец, третью.
*********** *********** ***********
становится
*********** *********** ***********
что становится
*********** *********** ************
и наконец
*************************************
Беспрерывный перечень величин компьютер может запомнить довольно просто, но как он потом находит пятый элемент во втором ряду?
Если компьютер знает сколько элементов находится в каждом ряду, то он может пройти это число элементов и начать считать во втором ряду, пока не дойдет до пятого элемента. Так же и для других рядов.
Для того, чтобы компьютер запоминал и определял элементы, ему надо сообщить число размеров и число элементов в каждом размере.
.шп14
19.4 Установка размеров массивов (DIM)
.шп1
Процесс установки размеров массивов используется для объявления необходимого количества размеров (или индексов) и диапазон величин, необходимых для каждого индекса.
.шп0
DIM price(20) оставит место для массива элементов, к которому обращаются как к массиву от price(0) до price(20), т.е. всего 21 элемент.
Введите NEW и следующую программу.
10 mode := 6 20 dim price(20) 30 // 40 for number := 0 to 20 50 print price(number) 60 next number
Запустите программу.
.шп1
Когда определяются размеры числового массива, то все величины обнуляются. Когда определяются размеры строкового массива, то все строки являются нулевыми строками, т.е. "".
.шп0
Сейчас добавьте
45 price(number) := rnd(99)
и просмотрите.
Эта программа поставит случайное число от 1 до 99 в каждый элемент массива. Компьютер затем получает величину из элемента и печатает ее.
Запустите программу.
С помощью прямой команды можно найти любой отдельный элемент.
Введите
print price(20)
.шп2
Установка границ массива
В нашем примере границы (или пределы) массива были установлены указанием размеров DIM price(20) на 0 и 20.
Иногда мы не очень хотим, чтобы нижняя граница была равна нулю или 1. Предположим, что мы хотим вести счет при игре в кости.
Мы можем использовать указание размеров для ограничения границ, напр. DIM score(2:12). Бывают случаи, когда полезно установить отрицательные границы.
.шп1
Нижние и верхние границы индекса могут быть определены при задании размеров массива. Например:
DIM diagonal#(-7:7) создаст одноразмерный массив целых от diagonal#(-7) до diagonal#(7).
DIM piece¤(1:8,1:8) создаст двухразмерный строковый массив от piece¤(1,1) до piece¤(8,8).
При задании размеров строкового массива для него оставляется такое же пространство, что и для строки, т.е. 40 позиций.
.шп0
При желании, с помощью команды OF, можно резервировать больше или меньше места, например: DIM initial¤(1:100) OF 5. Эта команда зарезервирует 5 позиций для каждого из элементов от initial¤(1) до initial¤(100): Это зарезервировало бы 100 раз по 35 позиций памяти, т.е. всего 3500 - очень значительное число.
.шп1
Изменить размеры уже существующего массива нельзя, как нельзя изменить и установленную длину строки элементов массива.
.шп14
19.5 Пример программы
.шп0
Сейчас мы составим программу для вывода на экран, иммитирующую результаты 60 бросков двух костей.
Процесс задания размеров массива и подготовки компьютера обычно называется инициализацеей.
Программа делится на следующие этапы: инициализация, показ заголовков, сам показ и конец.
Введите new и следующие строки
100 // Frequency Chart 110 // 120 MODE := 6 130 // 140 INITIALISE 150 HEADINGS 160 DISPLAY 170 FINISH 180 //
Строки 140 и 170 вызывают процедуры, которые формируют программу.
Если сейчас мы сможем написать процедуры, то программа будет закончена.
Мы можем поместить процедуры на заранее подготовленных строках, обычно начинающихся с круглых чисел.
Введите
1000 proc initialise
1080 end proc 1090 // 1100 proc headings
1180 end proc 1190 // 1200 proc display
1280 end proc 1290 // 1300 proc finish
1380 end proc 1390 // 1400 end
Запустите программу.
Если ничего не происходит, то программа структурно правильная. Если появляется сообщение об ошибке, то выведите программу на экран и проверьте каждую строку.
Мы можем произвести 60 наборов результатов бросков двух костей. Введите
1210 for shake := 1 to 60 1220 die_1 := rnd(6) 1230 die_2 := rnd(6) 1240 sum := die_1 + die_2 1250 print die_1,die_2,sum 1260 next shake
Просмотрите программу, а затем запустите ее.
Если мы хотим сложить количество тех раз, когда встречается 2, 3 и т.д. , то нам может помоч массив с индексом от 2 до 12.
Это должно быть сделано в процедуре инициализации.
Введите
1010 dim score(2:12)
Каждый раз, когда сумма равна 2,нам нужно, чтобы элемент score(2) увеличивался на 1, аналогично и с другими элементами.
Введите
1245 score(sum) := 1
Запустите и просмотрите программу.
Массив от score(2) до score(12) ссумировал все двойки, тройки и т.д. до дюжин. Чтобы узнать сколько раз выпадало семь, нужно ввести
print score(7)
Интересно посмтреть, как возрастал счет от броска к броску.
Добавьте
1110 print tab(0,20);"Score.2..3..4..5..6..7..8..9..10.11.12."''"Total"
Измените 1250 на
1250 print tab(3*sum,22);score(sum)
Строка 1250 печатает score(sum), когда он меняется.
Просмотрите и запустите программу.
Улучшение показа
Мы можем сделать вывод на экран более интересным, печатая над счетом звездочку каждый раз, когда он появляется. Однако TAB работает в верхней части экрана. Это значит, что необходимо табулировать вдоль экрана до счета и вниз по мере роста score(sum). Первая звездочка появится в 19 ряду, вторая в 18 и т.д.
Добавьте
1255 print tab(3*sum,20 - score(sum));"*"
Запустите программу.
Для заголовка очистите экран, затем введите
1120 print tab(0,2);"Frequency Chart" 1130 print "for 60 throws" 1140 print "of two dice."
И запустите программу.
.шп14
19.6 Включение и выключение курсора
.шп0
Чтобы улучшить впечатление от работы нашей программы, мы можем использовать одну из команд VDU.
Мигание курсора при его движении по экрану может отвлекать. Имеются команды VDU, которые выключают и включают курсор.
Очистите экран и затем, не забывая о пробелах, запятых и точках с запятой, введите
1020 vdu 23,1,0;0;0;0; // cursor off
и
1310 vdu 23,1,1;0;0;0; // cursor on 1320 print tab(0,5); // park cursor
Полностью программа выглядит так:
100 // Frequency Chart 110 // 120 MODE := 6 130 // 140 initialise 150 headings 160 display 170 finish 180// 1000 PROC initialise 1010 DIM score(2:12) 1020 VDU 23,1,0;0;0;0; // cursor off 1080 END PROC initialise 1090 // 1100 PROC headings 1110 PRINT TAB(0,20);"Score.2..3..4..5..6..7..8..9..10.11.12"''"Total" 1120 PRINT TAB(0,20);"Frequency Shart" 1130 PRINT "for 60 throws" 1140 PRINT "of two dice." 1180 END PROC headings 1190 // 1200 PROC display 1210 FOR shake := 1 TO 60 DO 1220 die_1 := RND( 6) 1230 die_2 := RND( 6) 1240 sum := die_1 + die_2 1245 score(sum) :+ 1 1250 PRINT TAB( 3*sum,22);score(sum) 1255 PRINT TAB( 3*sum,20 - score(sum));"*" 1260 NEXT shake 1280 END PROC display 1290 // 1300 PROC finish 1310 VDU 23,1,1,0;0; ;0//cursor on 1320 PRINT TAB( 0,5); // park cursor 1380 END PROC finish 1390 // 1340 END
.шп14
19.7 Итоговые упражнения
.шп0
Запишите свои ответы и сверьте их с ответами в главе 43.
Какие команды зададут размеры следующим массивам?
1. Одноразмерный строковый массив, name¤, с границами от 0 до 50.
2. Одноразмерный массив целых, points#, с границами от 10 до 80.
3. Двухразмерный массив, grid, с границами от 1 до 3 для каждого индекса.
4. Двухразмерный массив, ref_number, с границами от 1 до 3 для первого индекса и от 1 до 50 для второго.
5. Трехразмерный массив, item¤, с границами от 0 до 5 для каждого индекса.
6. Повторите вопрос 5, резервируя толко пять позиций для каждого элемента.
7. Напишите программу, которая READ (считает) из DATA (данных) в массивы name¤ и cost# названия пяти элементов и цену этих элементов в пенсах.
8. Сделайте дополнения к программе в вопросе 7 так, чтобы после того, как были считаны данные, показывались названия, элементы и цены, а также был обеспечен ввод номера каждого требуемого элемента. Итогова цена должна быть просчитана и выведена на экран.
.шп14
19.8 Выводы
.шп0
1. Массив - это комплект переменных, к которым обращаются с одним названием, но позиция которых определяется индексами, например: surname¤(89) или sum(4,2) или place#(2,3,4).
2. Перед использованием массива необходимо задать его размеры,напр. DIM surname¤(100) или DIM sum(10,10).
3. Границы размера в массиве могут быть выбраны и они могут включать отрицательные величины. Если нижняя граница не определена, то она устанавливается на 0, например: DIM total(2:12) позволяет использование от total(2) до total(12).
4. В массиве можно использовать до восьми размеров. Пример:
DIM coin¤(1:2,1:2,,1:2,1:2,1:2,1:2,1:2,1:2).
5. Когда задаются размеры числовому массиву, все его элементы устанавливаются на нуле. Когда задаются размеры строкового массива, все его элементы устанавливаются на нулевые строки.
6. Для каждого элемента строкового массива резервируется 40 позичий, если длина не устанавливается с помощью ключевого слова OF. Пример: DIM postcode¤(100) OF 9 зарезервирует девять позиций для каждого из 101 элемента массива OT postcode¤(0) до postcode¤(100).
7. Нельзя изменять размеры существующего массива. Также нелзя изменять установленную длину элементов строкового массива.
.ст комал10
[an error occurred while processing this directive]