Призначення програми.

ALGO - - одна з перших оболонок, яка розроблена не для професійного програмування, а для навчання програмуванню.
Так історично склалося, що програмування всі вивчали, користуючись професійними системами. Це було зрозуміло і на старих великих обчислювальних машинах, і на перших персональних комп'ютерах з вбудованою мовою Бейсик або однозадачною операційною системою MS DOS. Багатозадачні операційні системи з інтуїтивно зрозумілим для користувача інтерфейсом (MAC OS, Windows, Linux та ін.) витіснили старі системи разом зі старими комп'ютерами.
Однак програмне забезпечення для програмування настільки ускладнилось, що стало практично недоступне для початківців, які мають зрозуміти поняття змінної, виразу, умови, циклу і т.д. Повертатися з цією метою до текстового Бейсика чи Tubo Pascal для DOS не хотілося, тому і було створене ALGO - середовище із загальноприйнятим сучасним графічним інтерфейсом і простою мовою програмування.
Ми маємо лабораторне обладнання для вивчення більшості предметів. ALGO - навчальна система програмування , тобто аналог лабораторного обладнання для вивчення програмування. Це перша реалізація і, як в кожній справі, перша спроба не завжди дає досконалий результат. Ваші зауваження допоможуть усунути наявні недоліки та помилки.

Відповідність до інших систем програмування.

В середовищі ALGO реалізована мова програмування Pascal. Однак вибрані тільки ті елементи мови, які необхідні початківцю для розуміння основ програмування. В цьому розділі перелічені основні відмінності реалізованої мови від мови середовища Turbo Pascal.
Не підтримуються вказівники, об'єкти, UNIT, USES.
Не реалізовані множинні, перелічувані та діапазонні типи.
Файли підтримуються тільки текстові.
В наступних версіях ALGO будуть по черзі зніматись ці обмеження, про що буде вказано в цьому розділі.


Користування оболонкою.

Для того, щоб виконати програму, написану мовою Паскаль, необхідний комрілятор, який перекладе цю програму в коди комп'ютера. Але для цього потрібен текстовий файл з програмою на Паскалі. Щоб підготувати такий текст потрібно скористуватись екранним редактором. Крім того потрібно вміти запустити програму на покрокове виконання, мати засоби роботи з файлами, перегляду проміжних результатів та багато іншого. Всі ці засоби, зібрані разом, назвемо програмним середовищем, а вигляд цього середовища на екрані (вікна, меню, кнопки) - оболонкою.
На малюнку поданий вигляд оболонки ALGO і показані основні його елементи.

Оболонка виконана двома мовами - англійською та українською. Для переходу на англійську мову треба натиснути кнопку [image], а на українську - кнопку [image]. Це ж можна зробити з клавіатури натисканням Ctrl+E та Ctrl+U відповідно, або через меню (Опції Англійська мова; Опції Українська мова)
Для переходу до меню вказують мишкою на відповідний його пункт або натискають клавішу Alt, вибирають потрібний пункт клавішами керування курсором, після чого натискають Enter.
Мова оболонки ніяк не пов'язана з режимом роботи клавіатури. Для переключення клавіатури з латинських букв на кириличні і навпаки в більшості випадків використовують правий Ctrl+Shift. Це треба виясняти у викладача або власника комп'ютера. Але завжди можна переключити режим роботи клавіатури за допомогою іконки в правому нижньому кутку екрану, як показано на малюнку.

Звертайте увагу на вікно режиму роботи програми. Підготовка та виправлення тексту програми дозволяється тільки в режимі редагування.
У вікні заголовка вказано повний шлях та ім'я файлу програми, з яким Ви працюєте. Коли цієї інформації нема, то це означає, що Ви не записували програми на диск. Рекомендується записувати програму після набору кожних 10 - 20 рядків тексту та перед першим виконанням. Інакше в результаті помилкових дій чи збою програми підготовлений Вами текст програми може бути втрачений.
Щоб полегшити розуміння алгоритмічних конструкцій, в оболонку включений робот-вантажник. При зчитуванні програми, що використовує команди робота, відповідне вікно відкривається автоматично. В інших випадках це вікно треба відкривати вибором пунту Опції Робот в меню. Ця ж операція закриває вікно робота.
Таким чином, в загальному випадку програма підримує три вікна. Їх можна по-різному розміщувати на екрані. Для цього використовують пункт меню Вікно або відповідні кнопки панелі інструментів. Початківцям рекомендується використовувати режим поділу вікна, щоб всі вікна було видно одночасно.


Редагування тексту програми.

Для вказання місця, на яке записується введений з клавіатури текст, використовується курсор - мигаюча вертикальна риска. Введений символ завжди записується перед курсором, а наявний текст розсувається на одну позицію. Символи переходу на новий рядок (Enter) та пробіл (довга клавіша внизу клавіатури) опрацьовуються так само, як і решта символів.
Курсор можна перемістити за допомогою клавіш керування курсором, вертикальної та горизонтальної полос прокрутки та натисканням лівої кнопки мишки у відповідній позиції. Курсор ніколи не встановлюється поза текстом. Наприклад, коли Ви вкажете позицію після рядка, то курсор буде встановлений на кінець рядка.
Витерти неправильний символ перед курсором можна клавішею BackSpace, а після курсора - клавішею Delete.
При виправленні програм часто виникає необхідність витерти чи переставити в інше місце великі фрагменти тексту (блоки). Для цього передбачені так звані блочні операції. Щоб помітити блок треба поставити курсор на його початок і, тримаючи натисненою клавішу Shift, перемістити курсор до кінця блоку. Блок при цьому буде виділений чорним кольором. Це ж можна зробити мишкою: натиснути ліву кнопку на початку блоку і провести до кінця, не відпускаючи кнопки. Помітка автоматично анульовується будь-якою операцією переміщення курсора.
З поміченим блоком можна виконувати такі операції:
вилучити клавішею Delete;
вилучити і запам'ятати в спеціальному буфері натисканням кнопки [image] на панелі інструментів або вибором пункту Редактор Вилучити в меню, або натисканням Shift+Delete на клавіатурі;
скопіювати в буфер натисканням кнопки [image] на панелі інструментів або вибором пункту Редактор Скопіювати в меню, або натисканням Ctrl+Insert на клавіатурі;
вставити вміст буфера в текст програми на місце курсора натисканням кнопки [image] на панелі інструментів або вибором пункту Редактор Вставити в меню, або натисканням Shift+Insert на клавіатурі.
В буфері одночасно може знаходитись лише один фрагмент тексту, який зберігається протягом всього часу роботи програми. Це дає можливість переставляти фрагменти тексту з одного файлу в інший.
ALGO передбачає можливість автоматичного впорядкування тексту програми (запису кожного оператора з нового рядка, відступів перед вкладеними операторами і т.п.). Для виконання цієї операції натисніть кнопку [image] на панелі інструментів або виборіть пункт Редактор Впорядкувати в меню.
Для спрощення підготовки програми забезпечена можливість вставки в програму операторів, описів та інших конструкцій, які можна вибирати з меню Шаблони. Це ж меню можна активізувати клавішею F10 або натисканням правої кнопки мишки. Вибраний текст вставляється в програму на місце курсора. Цим же меню користуються для визначення складових R, G, B потрібного кольору.


Зчитування та запис програм.

Для того, щоб зчитати (завантажити) програму з диску, треба натиснути кнопку [image] на панелі інструментів або вибрати пункт Файл Прочитати в меню, або натиснути клавішу F3. На екрані появиться вікно системного діалогу, яке має такий вигляд.

За допомогою цього діалогу Ви можете вибрати і прочитати будь-який доступний текстовий файл. Не можна вводити імена файлів, яких немає. Для того, щоб створити новий файл, треба натиснути кнопку [image] на панелі інструментів або вибрати пункт Файл Новий в меню, або натиснути клавішу F4.
Аналогічним способом записують (зберігають) файли на диску. Для цього треба натиснути кнопку [image] на панелі інструментів або вибрати пункт Файл Записати в меню, або натиснути клавішу F2. Вікно системного діалогу має такий самий вигляд. Коли Ви записуєте новий файл, то обов'язково слід ввести з клавіатури його ім'я у відповідному вікні діалогу. якщо при цьому буде вказане розширення (.pas, .dat, .txt), то файл буде записаний з цим розширенням, інакше система автоматично запише файл з розширенням .pas.
При потребі запису файлу в нову папку (підкаталог) можна створити її за допомогою цього ж діалогу, натиснувши кнопку [image].


Виконання та відлагодження програми.

Щоб виконати програму треба натиснути кнопку [image] на панелі інструментів або вибрати пункт Команди Виконати програму в меню, або натисути клавішу F9.
Як не прикро, але в більшості випадків замість очікуваного результату виконання отримуємо повідомлення про помилку в програмі. ALGO виділяє червоним кольром рядок, в якому припинилася компіляція і встановлює курсор на місці зупинки. Це не завжди означає, що саме в цьому рядку допущено помилку. Наприклад, якщо курсор встановлений на початку виділеного рядка, а в тексті повідомлення є слово "пропущено", то це в більшості випадків означає, що пропущено щось в попередньому рядку.
При виконанні програми зеленим кольром виділяється рядок, який виконується, а у вікні режиму роботи вказаний поточний режим.
Кнопкою [image] або клавішею F6 завжди можна припинити виконання програми.
Відсутність синтаксичних помилок в програмі ще не означає, що програма правильна. В багатьох випадках отриманий результат є неправильним. В такій ситуації проводять відлагодження програми. Для цього виконують програму по одному оператору або частинами, контролюючи проміжні результати.
Щоб виконати один оператор програми натисніть кнопку [image] - Виконати наступний оператор або [image] Трасувати програму. Якщо наступним оператором не є оператор звертання до процедури, то в обох випадках буде виконаний наступний оператор програми. Коли ж використовується звертання до процедури або функції, то в першому випадку буде виконаний наступний оператор програми, а у випадку трасування програми - перший виконуваний оператор процедури чи функції.
Щоб пропустити великий фрагмент програми або довгий цикл, треба мишкою встановити курсор на потрібному місці зупинки і натиснути кнопку [image] Виконати до курсора. Ці ж команди можна подавати вказаними в меню функціональними клавішами.
Рядок програми, на якому припинилося виконання помічений зеленим кольором, а курсор встановлений на початку оператора, який має виконуватися. Для перегляду значень змінних в цьому режимі достатньо навести вказівник мишки на змінну і залишати його нерухомим одну секунду. Програма в маленькому жовтому віконечку виведе ім'я змінної, її тип та значення.

Значення виводиться тільки для простих змінних. Якщо потрібно подивитися значення елемента масиву чи поля запису, використовують вікно перегляду значень, яке викликають натисканням правої кнопки мишки або функціональної клавіші F10. При цьому появляється діалог перегляду значень. Необхідно ввести ім'я потрібної змінної та натиснути Enter і програма виведе інформацію про змінну. Вікно перегляду значень є так званим вікном-поплавком, яке весь час знаходиться зверху. Це дозволяє користуватись ним для спостереження за змінною в процесі покрокового виконання програми.


Користування довідковою системою.

Довідкова система середовища ALGO побудована з використанням стандартних засобів операційної системи Windows. Наведемо лише основні прийоми роботи з довідкою. При натисканні клавіші F1 довідкова система активізується і переходить до розділу, в якому описане слово, на яке вказував курсор в момент натискання клавіші. Якщо такого розділу немає, то виводиться зміст всіх розділів. В цьому випадку потрібно відшукати по змісту потрібний розділ і вивести його подвійним натисканням кнопки мишки.
Щоб виконати приклад програми, наведеної в довідковій системі, необхідно виконати такі дії:
1. Помітити текст програми. Натиснувши ліву кнопку мишки на початку програми, перемістити вказівник до кінця програми не відпускаючи кнопки. Текст програми повинен виділитись чорним кольром.
2. Помістити вказівник на виділений текст і написнути праву кнопку мишки. Вибрати пункт "Копіювати" в меню.
3. Створити и ALGO нову програму.
4. Вставити скопійований текст натисканням кнопки

Після цього можна виконувати програму.


Використання робота.

Модель робота-вантажника використана в середовищі ALGO з двох причин. По-перше, за його допомогою Ви можете зрозуміти принципи керування різними механічними пристроями. По-друге, так легше вивчати алгоритмічні конструкції, бо виконання будь-якої команди візуально відображається на екрані.
Робот працює в певній обстановці, схему якої можна редагувати, якщо програма працює в режимі редагування. Для цього користуються панеллю інструментів робота.

Використання панелі очевидне, біжучий режим ілюструє форма курсора. Підготовлену схему можна записати на диск для повторного використання. Рекомендується записувати схему з такою самою назвою, як програму, для якої вона підготовлена.
Щоб краще зрозуміти можливості робота, можна скористатися режимом ручного керування. Натиснувши відповідну кнопку на панелі інструментів, Ви отримаєте таке вікно діалогу.

Натискаючи на відповідні кнопки, Ви посилаєте роботу команди. Він виконує ці команди, або повідомляє про помилку.
На перший погляд команди опитування виглядають зайвими. Справді, навіщо питати, чи вільний шлях перед роботом, якщо ми це бачимо самі. Але ж комп'ютер не бачить! Щоб зрозуміти необхідність команд опитування, пересуньте вікно пульта керування так, щоб воно закрило вікно робота. Тепер попробуйте вивести робота до виходу.


Мова програмування.


Основні поняття.

В цьому розділі описаний алфавіт мови Паскаль, вводиться поняття імені (ідентифікатора), дані вказівки з правильного оформленн програм.


Символи і зарезервовані слова.

Символами (лексемами) називаються мінімальні значимі одиниці тексту в програмі, написаної на Паскалі.
Програма, написана на Паскалі, складається з лексем і роздільників, причому роздільник являє собою пробіл, перехід на новий рядок або коментар. Лексеми подані такими категоріями як спеціальні символи, ідентифікатори, мітки, числа і рядкові константи. Дві сусідніх лексеми, якщо вони являють собою зарезервоване слово, ідентифікатор, мітку або число, повинні бути відділені одна від одної одним або кількома роздільниками. Роздільники не можуть бути частиною лексем, за винятком рядкових констант.
Спеціальні символи і зарезервовані слова.
Паскаль використовує такі підмножини набору символів коду ASCII:
- Букви англійського алфавіту від A до Z і від a до z.
- Букви українського алфавіту від А до Я і від a до я.
- Арабські цифри від 0 до 9.
- Пробіли - символ пробілу (ASCII 32) і усі керуючі символи коду ASCII, включаючи символ кінця рядка або символ повернення (ASCII 13).
Спеціальні символи і зарезервовані слова являють собою символи, що мають одне або кілька фіксованих значень. Спеціальними символами є такі одиночні символи:
+ - * / = < > [ ] . , ' ( ) : ; { }
Такі пари символів також являють собою спеціальні символи:

Деякі спеціальні символи є також знаками операцій.
Нижче наведена таблиця зарезервованих слів мови Паскаль та їхніх перекладів, які використовуються при роботі ALGO українською мовою.
and | та | array | масив
begin | початок | case | випадок
const | константи | div | div
do | виконати | downto | вниздо
else | інакше | end | кінець
for | для | function | функція
if | якщо | mod | mod
not | не | of | із
or | або | procedure | процедура
program | програма | record | запис
repeat | повторювати | then | то
to | до | type | типи
until | покине | var | змінні
while | поки | label | мітки
goto | йтидо | string | рядки
Тут зарезервовані слова записані малими літерами. Проте, для Паскалю байдужний регістр клавіатури, тому ви можете використовувати у своїй програмі як великі, так і малі букви.
На вiдмiну вiд багатьох реалiзацiй програмних оболонок з компiлятором Паскалю ця оболонка допускає використання букв українського алфавiту в конструкцiях мови.


Імена (ідентифікатори).

Ідентифікатори виступають у якості імен констант, типів, змінних, процедур, Функцій, програм та полів у записах. Ідентифікатор може мати довжину до 16 символів.
Ідентифікатор повинен починатися з букви і не повинен містити пробілів. Після першого символу допускають букви, цифри і знак підкреслення _. як і зарезервовані слова, ідентифікатори байдужні до регістра клавіатури.
Приведемо кілька прикладів ідентифікаторів:
G, alfa, test17, x2y,
Сума2Чисел, кінець_масиву.
 Надалі слова “ім’я” та “ідентифікатор” вживатимемо як синоніми.
В ALGO ідентифікатори, які означають імена стандартних типів, функцій та процедур, виділяються червоним кольром. Мова Паскаль не забороняє використовувати ці імена для позначення інших змінних, але робити це не рекомендується, бо змінні з іменами sin, write і т.п. заплутують автора програми та інших програмістів.


Коди ASCII.

Для запису одного символа в пам'яті виділяється один байт (8 біт). В одному байті можна записати 256 різних кодів, які можна вважати цілими числами вид 0 до 255. Для кодування символів складена таблиця кодів, в якій кожному символу відповідає ціле число. Перша частина цієї таблиці є міжнародним стандартом (американський стандартний код для обміну інформацією - ASCII). Друга частина містить літери національних алфавітів та спеціальні символи. Порядок їх розміщення в таблиці регулюється національними або міждержавними стандартами.
Коди з 0 до 31 є службовими і тут не наводяться. Серед них:13 - код кінця рядка, 26 - код кінця файлу.


Рекомендації з оформлення програм.

Пишіть програми так, щоб їх можна було зрозуміти не тільки Вам, а й іншим людям. Для цьго:
Надавайте змінним такі імена, які відповідають назві іменованої величини.
Кожен оператор намагайтеся писати з нового рядка.
Робіть відступи перед вкладеними операторами.


Пояснення до програми (коментарі).

Будь- який текст, взятий в фігурні дужки або обмежений парами символів (* *) є коментарем та ігноруються компілятором:
{будь-який текст, що не містить праву фігурну дужку}
(*будь-який текст, що не містить зірочку/праву круглу дужку*)
 Коментарі в ALGO виділяються зеленим кольром.
При написанні програм, робота яких не є очевидною, бажано писати коментарі, щоб інший програміст міг зрозуміти їх.


Структура програмного модуля.

Кожна програма, процедура чи функція складається з заголовку та тіла програмного модуля, яке надалі будемо називати блоком.
Заголовки процедури та функції описані в окремому розділі.
Заголовок програми є суто декоративною деталлю, бо вказана в ньому інформація не використовується ніде. Але заголовок є обов'язковим і записується в такому вигляді:
Program назва;
Програма назва;
Зауважимо, що назва програми ніяк не пов'язана з іменем файлу, у якому ця програма записана.
Після заголовку записують блок, який завершується словом end, після якого ставиться крапка.

Структура блоку.

Блоки складаються з описів, що записані в певному порядку, і операторів. Всі ідентифікатори і мітки, описані в розділі описів даного блоку, є для блоку локальними, тобто доступні тільки в цьому блоці.
У загальному вигляді будь-який блок має такий формат:
розділ опису міток;
розділ опису констант;
розділ опису типів;
розділ опису змінних;
опис процедур та функцій;
begin
оператор1;
.....................
операторN
end
В кожному конкретному випадку задаються лише необхідні для даного програмного модуля розділи описів, але порядок їх слідування повинен строго відповідати приведеній схемі.
Наведемо приклад програми, яка виводить квадрати введених чисел, поки не буде введений нуль.
Program test;
Var
i : integer;
Begin
repeat
Read ( i );
WriteLn ( sqr ( i ) );
until i = 0
end.


Числа, символи, рядки.

Для чисел, що є константами цілого і дійсного типу, використовується звичайний десятковий запис. Для відокремлення цілої частини дійсного числа від дробової використовують крапку. В Паскалі дійсне число не може починатися з крапки. Технічне позначення (Е або е з показником) у дійсних типах читається як "на десять у ступені". Наприклад, 7.3Е-3 означає [image] тобто 0.0073. Числа з десятковими крапками або экспонентами являють собою константи дійсного типу. Числа без десяткової крапки та експоненти позначають константи цілого типу. Вони повинні приймати значення в діапазоні від -2147483648 до 2147483647. Знак перед числом в програмі не належить до числа, а є унарною операцією.
Рядок символів являє собою послідовність, що містить нуль або більше символів із розширеного набору символів коду ASCII, записану в одному рядку програми й укладену в одиночні лапки (апострофи). Рядок символів, який нічого не містить між апострофами, називається нульовим рядком. Два послідовних апострофи в рядку символів позначають один символ - апостроф. Атрибут довжини рядка символів виражається справжньою кількістю символів між апострофами.
Рядок, який містить один символ, є константою символьного типу, а рядок іншої довжини - константою рядкового типу.


Змінні.

Поняття змінної в програмуванні достатньо близьке до звичного для нас математичного поняття. В математиці, фізиці змінною ми називаємо деяке символічне позначення величини, яка може набувати різних значень. Причому змінна - це не завжди число. Вектори, матриці та більш складні структури теж позначають буквами і називають змінними. Змінним, функціям і типам бажано надавати такі імена, щоб при читанні програми відразу було зрозумілим призначення даного ідентифікатора.
Обчислювальна машина обробляє інформацію, записану певним способом в оперативній пам'яті. Для символа тексту, цілого чи дійсного числа, логічного значення в пам'яті виділяється ділянка необхідного розміру, в яку може бути записана інформація. Отже для кожної одиниці інформації треба знати місце її розміщення в пам'яті (адресу), та спосіб (формат) запису.
Пам'ять, необхідна для розміщення величин, що міняються в процесі роботи програми (змінних), виділяється компілятором автоматично. Кожній змінній ми надаємо ім'я, яке однозначно ідентифікує її, (ідентифікатор). Для того, щоб компілятор міг визначити розмір пам'яті для змінної та формат запису її значення, необхідно вказати її тип, тобто описати її.
Ідентифікатор описаної змінної вказує адресу в пам'яті, де записано її значення, а також розмір і формат запису цього значення.
Якщо ідентифікатор зустрічається у виразі, то це означає, що треба прочитати з пам'яті і використати для обчислень значення змінної. Якщо в лівій частині оператора присвоєння, то записати значення в ділянку пам'яті, яка виділена для змінної.
ALGO перед використанням значення змінної перевіряє, чи даній зінній було надане якесь значення.


Розділ опису міток.

В цьому розділі оголошуються мітки, що привласнюються операторам. Кожна мітка повинна помічати тільки один оператор. Всі мітки перед вживанням повинні бути оголошені за допомогою такого запису:
Label мітка1,мітка2,...міткаN;
Мітки мітка1,мітка2,...міткаN;
 Міткою є послідовність цифр, тобто ціле число без знаку, яке знаходиться в діапазоні від 0 до 9999. Нулі перед числами ігноруються.
Мітки є локальними для блоку, в якому вони описані. Для інших блоків (в тому числі вкладених) мітки даного блоку невидимі.
Мітки використовують в операторах переходу.


Розділ опису констант.

Розділ опису констант служить для іменування довгих або часто вживаних чисел чи рядків тексту. Оголошені в цьому розділі константи використовуються так само, як змінні, але їм не можна надавати інших значень. Типи костант визначаються типами константних виразів, які стоять після знаку =.
Розділ починається зарезервованим словом const ( Константи ) , після якого слідує один або більше речень
ідентифікатор = значення;
в яких значення є числом, символом чи рядком.
Наприклад:
Const
v0 = 37.55;
alfa = 45;
прізвище = 'Микитин';


Розділ опису типів.

Крiм стандартних типiв можна створити типи змiнних, якi дiють лише у межах програмного модуля. Розділ опису типів починається зарезервованим словом Type ( Типи ), за яким записують одне або більше речень вигляду
ідентифікатор = опис_типу;
кожне з яких закінчується символом крапка з комою.
В цьому означенні опис_типу може бути записаний в одному з наступних варіантів:
- ідентифікатор стандартного типу;
- опис масиву;
- опис запису;
- ідентифікатор типу, описаного раніше.
Наведемо в такому самому порядку приклади опису типів.
Type
довжина = real;
Vector = array [1..15] of real;
товар = record
назва : string;
кількість, ціна : real;
термін : дата;
end;
швидкість = Vector;


Розділ опису змінних.

Розділ починається зарезервованим словом var ( змінні ), після якого слідує один або більше речень
CписокІмен : опис_типу;
Опис_типу для кожної групи імен може бути записаний в одному з наступних варіантів:
- ідентифікатор стандартного типу;
- опис масиву;
- опис запису;
- ідентифікатор типу, описаного раніше.
Приклади:
Var
Місто, Вулиця : масив [1..15] із символи;
ПлощаДороги, ПлощаКлумб : дісні;
КілБудинків, КілМешканців : цілі;


Стандартні типи змінних.

При описі змінної необхідно зазначити її тип. Тип змінної визначає набір значень, які вона може приймати, форму запису їх в пам’яті та дії, що можуть бути над нею виконані. Типи поділяються на прості та складні. Змінна простого типу завжди позначає одне значення (число, символ і т.п). Змінна складного типу позначає таблицю значень однакового типу (масив) або набір полів різного типу (запис). До простих типів в ALGO належать:
логічний тип boolean - логічні ;
символьний тип char - символи ;
цілий тип integer - цілі ;
дійсний тип real - дійсні .
Всі прості типи, крім дійсного, є порядковими. Всі можливі значення даного порядкового типу являють собою упорядковану множину, і кожне можливе значення пов'язане з порядковим номером, що являє собою ціле значення. За винятком значень цілого типу, перше значення будь-якого порядкового типу має порядковий номер 0, наступне значення має порядковий номер 1 і так далі для кожного значення в цьому порядковому типі. Порядковим номером значення цілого типу є саме це значення. У будь-якому порядковому типі кожному значенню, крім першого, передує інше значення, і після кожного значення, крім останнього, слідує інше значення відповідно до упорядкованості типу.
Змінні лоігічного (boolean ) типу приймають одне з двох фіксованих значень, які позначаються стандартними ідентифікаторами констант false(ні) та true(так). При операціях порівняння для змінних логічного типу має місце співвідношення true>false.
Множиною значень символьного (char ) типу є символи, упорядковані відповідно до розширеного набору символів коду ASCII. При виклику функції Ord(Ch), де Ch - значення символьного типу, повертається порядковий номер Ch. рядкова константа з одиничною довжиною може позначати значення константи символьного типу. Будь-яке значення символьного типу може бути отримане за допомогою стандартної функції Chr.
Змінні цілого (integer ) типу можуть набувати значень з діапазону від –2147483648 до 2147483647 і займають в пам’яті 4 байти.
До дійсного типу відносить підмножина дійсних чисел, що можуть бути подані у форматі з плаваючою комою із фіксованим числом цифр. Дійсні числа в ALGO можуть мати порядок від Е+320 до Е-320.
Рядковий тип (string - рядки) займає проміжне становище між простими та складними типами. Значенням змінної рядкового типу є рядок символів із динамічним атрибутом довжини (у залежності від справжнього числа символів при виконанні програми) і постійним атрибутом розміру в діапазоні від 1 до 255.
Змінні рядкового типу можуть входити як операнди у вирази, аналогічно до змінних простих типів. До символів у рядку можна мати доступ як до компонентів масиву, що є властивістю складного типу.
В даній реалізації Паскалю наявний лише текстовий тип файлів text (текст), який визначає файл, що містить символи, упорядковані в рядки. Текстові файли використовують спеціальні процедури введення/виведення


Масиви.

Масиви містять фіксоване число компонентів одного типу, так званого типу конпонента. Границі масиву задаються піддіапазоном будь-якого порядкового типу за формою
array [ початок..кінець ] of опис_типу;
масив [ початок..кінець ] із опис_типу;
При цьому має виконуватись умова початок<=кінець, а опис_типу може бути записаний в одному з наступних варіантів:
- ідентифікатор стандартного типу;
- опис масиву;
- опис запису;
- ідентифікатор типу, описаного раніше.
Приведемо приклад типу масив:
array[1..100] of real;
Якщо тип елемента в типі масив також є масивом, то результат можна розглядати як масив масивів або як один багатомірний масив. Наприклад,
array[3..8] of array[‘a’..’f’] of real
інтепретується компілятором точно так само, як
array[3..8,‘a’..’f’] of real


Записи.

Тип запис містить установлене число елементів або полів, що можуть бути різноманітних типів. Опис типу запис вказує тип кожного поля та ідентифікатор, що іменує поле.
Record
CписокІмен1 : опис_типу1;
...........................
CписокІменN : опис_типуN;
end;

Запис
CписокІмен1 : опис_типу1;
...........................
CписокІменN : опис_типуN;
кінець;
Опис_типу для кожної групи імен, які називають полями запису, може бути записаний в одному з наступних варіантів:
- ідентифікатор стандартного типу;
- опис масиву;
- опис запису;
- ідентифікатор типу, описаного раніше.
Приведемо приклад типу запис:
Запис
Прізвище, Імя, По_батькові : рядки [15];
Зріст, Вага : дісні;
РікНародження, НомерКарточки : цілі;
кінець;


Опис процедур та функцій.

Опис процедури або функції складається із заголовка та тіла (блоку), структура якого повністю аналогічна до структури програми.
Заголовок процедури має вигляд:
Procedure назва ( список_формальних_параметрів );
Процедура назва ( список_формальних_параметрів );
У заголовку процедури вказується ім'я процедури й описується список формальних параметрів (якщо він потрібний).
Запуск процедури здійснюється за допомогою оператора звертання до процедури.
Приведемо приклад опису процедури:
Procedure Change( a, b : integer );
var
i : integer;
begin
i := a; a := b; b := i
end;
У заголовку функції визначається ідентифікатор функції, формальні параметри (якщо вони є) і тип результату функції.
Function назва( список_формальних_параметрів ): тип;
Функція назва( список_формальних_параметрів ): тип;
Функція активізується при виклику функції. При виклику функції вказується ідентифікатор функції і параметри, необхідні для обчислення функції. Виклик функції може включатися у вирази в якості операнда. Коли вираз обчислюється, функція виконується і значенням операнда стає значення, яке повертається функцією.
В операторній частині блока функції повинен міститися принаймні один оператор присвоювання, у якому ідентифікатору функції присвоюється значення. Результатом функції є останнє присвоєне значення. Якщо такий оператор присвоювання відсутній або він не був виконаний, то значення, що повертається функцією, невизначене.
Якщо ідентифікатор функції використовується при виклику функції усередині модуля-функції, то функція виконується рекурсивно.
Приведемо приклад опису функції:
Function Max ( a : Vector; n : integer ) : integer;
var
i, x : integer;
begin
x := a(1);
for i := 2 to n do
if x < a[i] then x := a[i];
Max := x;
end;


Видимість (область дії) описів.

Змінні структурних типів (масиви і записи) займають в пам'яті великі ділянки і складаються з простих елементів. Для доступу до них використовують індекси масиву та імена полів запису. Тут лише наголосимо, що і структурний тип і його компоненти є змінними.Області дії описів (видимість імен). Наявність імені в одному з описових розділів означає визначення ідентифікатора. Щоразу, коли ідентифікатор зустрічаються в програмі, він повинен знаходитися в області дії цього опису. Область дії ідентифікатора поширюється від його опису до кінця поточного блоку, включаючи всі блоки, що входять у поточний блок. Ідентифікатори не можна використовувати доти, поки вони не описані, тобто опис ідентифікатора повинен передувати будь-якому входженню ідентифікатора в тексті програми.
Ідентифікатор поля запису описується в рамках типу запис має значення тільки в сполученні з посиланням на змінну цього типу запис. Тому ви можете повторно визначити ідентифікатор поля (із таким же написанням) у тому ж самому блоці, але не на тому ж самому рівні в рамках зазначеного типу запис. Проте, ідентифікатор, що був раніше описаний, може бути повторно визначений як ідентифікатор поля в тому ж самому блоці.
Правила для обдасті дії описів покажемо на такому прикладі. Нехай в програмі Test описані модулі Alfa та Omega, а в процедурі Alfa описані модулі Beta та Gamma, як показано на малюнку. В модулях описані зінні, імена яких написані червоним кольром.

Змінні D,E є глобальними, тобто їх можна використовувати у всіх блоках і всюди вони позначають одну і ту ж область пам’яті та мають однакове значення. Змінні M,N доступні тільки в процедурі Omega.
Змінна А доступна всюди, але у функції Gamma вона є локальною, тобто А в цій функції позначає зовсім іншу область пам’яті. Значення змінної А у функції Gamma ніяк не пов’язано зі значенням цієї змінної у всіх інших модулях.
Змінні В,С доступні в модулях Alfa, Beta, Gamma, але для модуля Beta змінна В є локальною, тобто її значення в процедурі Beta ніяк не пов’язано зі значенням цієї змінної в процедурі Alfa.
Такі ж правила стосуються імен процедур та функцій. До процедур Alfa та Omega можна звертатись з будь-якого місця, до Beta – тільки всередині Alfa і Beta, до Gamma – тільки всередині Alfa і Gamma.


Виконувані оператори (команди).

Програма - це деякий алгоритм перетворення та пересилки інформації, записаний конкретною мовою програмування. На відміну від описового подання алгоритму, яке передбачає читання його людиною, в програмі кожен крок алгоритму мусить бути записаний у формі однієї з небагатьох інструкцій, які компілятор здатний переписати в кодах машини. Такі інструкції (англійською мовою statement - вислів, наказовий вислів, вказівка) у вітчизняній літературі отримали назву оператори.
Розглянемо оператори мови Паскаль.
Оператор присвоєння обчислює значення виразів і записує отриманий результат в комірку пам'яті, позначену змінною.
Оператор переходу вказує, що наступним має бути виконаний не той оператор, який записаний після нього, а помічений міткою.
Оператор звертання до процедури передає керування окремому програмному модулю (процедурі), після виконання якого керування повертається наступному оператору.
Порожній оператор складається з єдиного символа крапка з комою і не виконує ніяких дій.
Умовний оператор дозволяє в залежності від деякої умови вибрати для виконання один з двох операторів, які входять до нього, або не виконати жодного.
Оператор вибору дозволяє вибрати для виконання один з багатьох операторів, які входять до нього, або не виконати жодного в залежності від значення деякої змінної.
Оператор циклу з передумовою повторює виконання іншого оператора,що входить до нього, 0 або більше разів, поки значення деякої умови не стане хибним.
Оператор циклу з післяумовою повторює виконання групи операторів,що входять до нього, 1 або більше разів, поки значення деякої умови не стане істинним.
Оператор циклу з параметром повторює виконання іншого оператора,що входить до нього, для всіх значень деякого параметра, які знаходяться в заданому діапазоні.
Складений оператор об'єднує групу будь-яких операторів в один оператор.


Оператор присвоєння.

Оператор присвоювання заміняє поточне значення змінної новим значенням, що визначається виразом.
змінна := вираз
Вираз повинний бути сумісний по присвоюванню з типом змінної.
Приведемо деякі приклади операторів присвоювання:
X := Y + Z
Done := (I>=1) and (I<100);
I := Sqr(J) - I*K;


Операції. Типи операндів та результату.

Найвищий пріорітет мають унарні операції.

До унарних операцій можна віднести також знак +, якщо він стоїть перед першим операндом, наприклад, +а*с. Це операція збереження знаку, яка не виконує ніякої дії, тому практично ніколи не використовується.
Другу групу складають так звані мультиплікативні операції.

Третю групу складають адитивні операції.

якщо обидва операнди в операціях +, -, *, div або mоd є операндами цілого типу, то тип результату буде цілим. якщо один або більше операндів в операціях +, -, або * мають дійсний тип, то тип результату буде дійсним. Значення виразу х/у завжди буде дійсного типу, незалежно від типів операндів. якщо у дорівнює 0, то буде виведене повідомлення про помилку. Значення вираз i div j являє собою математичну частку від i/j, округлену в меншу сторону до значення цілого типу. якщо j дорівнює 0, то буде виведене повідомлення про помилку. Операція mod повертає залишок від ділення двох її операндів, тобто:
i mod j = i - (i div j) * j
Знак результату операції mod буде тим же, що і знак i. якщо j дорівнює нулю, то результатом буде помилка.
Результати логічних операцій відповідають звичайній булевій логіці. Наприклад, вираз a and b є істинним (приймає значення truе) тільки в тому випадку, якщо обидва операнди a і b мають істинне значення (truе).
При повному обчисленні припускається, що кожний операнд логічного виразу, побудований за допомогою операцій or і and, завжди буде обчислюватися, навіть якщо результат усього виразу уже відомий.
Паскаль дозволяє використовувати операцію + для об'єднання двох рядкових операндів. Результатом операції s+ t, де s і t мають рядковий або символьний тип, буде об'єднання s і t. якщо довжина результуючого рядка перевищує 255 символів, то вона урізається до 255 символів.
В останню чергу виконуються операції відношення

Коли операції =, <>, <, >, >=, <= застосовуються для операндів простих типів, то це повинні бути сумісні типи. Проте, якщо один операнд має дійсний тип, то інший може бути цілого типу. Для цілого і дійсного типів операції відношення мають звичайний алгебраїчний зміст. З двох символів більший той, який стоїть має більший номер в таблиці кодів. Нарешті, true>false, хоч це рідко використовують.
Операції відношення можуть застосуються для порівняння рядків відповідно до порядку розширеного набору символів коду АSСII. Будь-які два значення рядкових даних можна порівняти, оскільки всі значення рядкових даних сумісні.
Відношення між будь-якими двома рядковими значеннями встановлюється відповідно до відношення порядку між значеннями символів у відповідних позиціях. У двох рядках різної довжини кожний символ більш довгого рядка без відповідного символу в більш короткому рядку приймає значення "більше". Наприклад, 'Xs' більше, ніж 'X'. Нульові рядки можуть бути рівні тільки іншим нульовим рядкам, і вони є найменшими рядковими значеннями.
Значення символьного типу сумісні зі значеннями рядкового типу, і при їхньому порівнянні символьне значення опрацьовується як рядкове значення з довжиною 1.


Вирази.

Вирази складаються з операцій і операндів. Операндами можуть бути константи, змінні, вирази в дужках та значення, які повертаються функціями. Більшість операцій у мові Паскаль є бінарними, тобто містять два операнди. Інші операції є унарними і містять тільки один операнд. У бінарних операціях використовується звичайне алгебраїчне уявлення, наприклад a+b. В унарних операціях операція завжди передує операнду, наприклад -b. У більш складних виразах порядок, у якому виконуються операції, відповідає пріоритету операцій. Спочатку вираховуються вирази в дужках, значення індексів масивів та значення функцій, потім виконуються операції з найвищим пріорітетом, потім з нижчим і т.д. Операції з однаковим пріорітетом виконуються зліва направо. Операнд, що знаходиться між двома операціями з різними пріоритетами, зв'язується з операцією, що має більш високий пріоритет.
По пріорітету виконання операції діляться на такі групи:
1. Унарні not - ;
2. Мультиплікативні mod div and * / ;
3. Адитивні or + - ;
4. Операції порівняння = < > <= >= <>.
Для зміни порядку виконання операцій використовують круглі дужки. як уже згадувалось на початку цього розділу, вирази в дужках обраховуються в першу чергу. Слід зауважити, що зайві дужки, наприклад a+(18*x+12*y), ігноруються компілятором. Коли Ви не впевнені в порядку виконання виразу, то користуйтесь дужками, бо вони в жодному випадку не можуть зробити програму гіршою.
Тип результату операції, яка виконується останньою при вирахуванні значення виразу, визначає тип самого виразу. Тому інколи вирази, що дають результат логічного типу, називають логічними виразами, хоча в них входять операції множення, додавання і т.п. Арифметичними виразами часто називають вирази, які дають результат цілого або дійсного типу.
Наведемо приклади виразів


Звертання до функцій, елементів масивів та полів у записах.

Значення функцій використовуються у виразах, як звичайні операнди. При цьому треба вказати список фактичних параметрів (аргументів), якщо такий список наявний в оголошенні функції, слідкуючи за відповідністю типів.
Доступ до елемента масиву отримують по його імені, після якого в квадратних дужках вказують вираз, який визначає номер елемента в масиві.
Поле запису в ALGO дентифікується тільки за допомогою імені змінної-запису, після якої вказують ім'я поля.Наприклад, якщо є змінна Список : масив [1..100] із
Запис
Прізвище,Імя,По_батькові : масив [1..15] із символи;
Зріст,Вага : дісні;
РікНародження,НомерКарточки : цілі;
кінець;
то Список[N].РікНародження дає доступ до поля РікНародження N-того пацієнта, а Список[N].Прізвище[1] - до першої літери його прізвища.Оператор присвоювання.


Складений оператор.

Складений оператор опрацьовується, як один оператор, що має вирішальне значення там, де синтаксис Паскалю допускає використання тільки одного оператора.
begin
оператор1;
........
операторN
end
Оператори записуються в операторні дужки begin і end, відокремлюються один від одного крапкою з комою та виконуються в порядку запису.
Зверніть увагу, що в Паскалі символ крапка з комою служить для відокремлення операторів один від одного, а не для завершення оператора. Тому після останнього оператора (перед ключовим словом end) крапку з комою ставити не потрібно. Однак, якщо вона є, то у випадку складеного оператора цей символ сприймається як порожній оператор (оператор, який не виконує ніяких дій). В інших випадках (в операторах if, де синтаксис вимагає запису одного оператора) наявність крапки з комою приводить до повідомлення про помилку.
Можна сформулювати таке правило: крапка з комою ставиться після оператора (в тому числі після слова end складеного оператора) у всіх випадках, крім тих, коли наступним словом є end, until або слово else оператора if.
Наведемо приклад складеного оператора:
begin
Z := X;
X := Y;
Y := Z
end;


Оператор переходу.

Оператор переходу викликає передачу керування оператору, якому передує мітка, зазначена в даному операторі переходу. Оператора переходу має такий вигляд:
GоTо мітка
ЙтиДо мітка
Міткою є послідовність цифр у діапазоні від 0 до 9999. Початкові нулі не є значущими. Наступним після оперетора переходу буде виконаний оператор, позначений вказаною міткою.
При використанні оператора переходу повинні дотримуватися такі правила:
1. Мітка, що вказується в операторі переходу, повинна знаходитися в тому ж модулі, що і сам оператор переходу. Іншими словами, не допускаються переходи з процедури або функції назовні або ззовні усередину її.
2. Перехід ззовні усередину структурного оператора (тобто перехід на більш глибокий рівень вкладеності) може викликати непередбачені ефекти, хоча компілятор не видає повідомлення про помилку. Наприклад, перехід всередину оператора циклу з параметром приводить до виконання частини тіла циклу при невідомих значеннях параметра та початкового і кінцевого значень.
Часте вживання оператора переходу робить програму заплутаною, тому його не рекомендують використовувати.
Приклад:
У випадку, коли потрібно негайно завершити виконання процедури при Х<0, можна скористатись переходом на порожній оператор, який є останнім у процедурі.
Procedure Test;
Label 11;
..........
Begin
.......
If X<0 then GoTo 11;
.......
11 : ;
end;


Умовний оператор.

Повний умовний оператор дозволяє вибрати для виконання один із складових операторів.
If вираз then оператор1
else оператор2

Якщо вираз то оператор1
інакше оператор2

Неповний умовний оператор виконує внутрішній оператор тільки в тому випадку, коли значення виразу є істинним (при виконанні умови).

If вираз then оператор

Якщо вираз то оператор

У виразі повинен утворюватися результат, що має стандартний логічний тип. якщо результатом виразу є істинне значення (true), то виконується оператор, що слідує за ключовим словом then. якщо результатом виразу є значення false і присутнє ключове слово else, то виконується оператор, що слідує за ключовим словом else, а якщо воно відсутнє, то ніякий оператор не виконується.
В обидвох частинах умовного оператора можна вживати лише по одному оператору. При необхідності помістити групу операторів, потрібно утворити з них складений оператор.
Синтаксична неоднозначність, що виникає в конструкції:
if e1 then if e2 then s1 else s2
 вирішується шляхом такої інтепретації цієї конструкції:
if e1 then
begin
if e2 then
s1
else
s2
end
 У загальному випадку ключове слово else зв'язується з найближчим ключовим словом if, що ще не пов'язано з ключовим словом else.
Приведемо приклад оператора if:
if X < 1.5 then
Z := X+Y
else
Z := 1.5;


Оператор вибору.

Оператор вибору (варіанту) складається з виразу (перемикача) і списку операторів, кожному з яких передує список констант, які називаються константами вибору, або ключове слово else. В кожному списку має бути хоча б одна константа. Перемикач повинен мати порядковий тип. Всі константи вибору повинні бути унікальними (зустрічатись лише один раз в даному операторі) і мати тип, сумісний із типом перемикача.
Case вираз оf
K11,...,K1M : оператор1
..................
KN1,...,KNL : операторN
else операторN1
end

Випадок вираз із
K11,...,K1M : оператор1
..................
KN1,...,KNL : операторN
інакше операторN1
кінець
В кожному варіанті записують лише один оператор, що може бути складеним оператором. Частина оператора, яка починається словом else, може бути відсутня.
Оператор вибору (варіанту) приводить до виконання оператора, перед яким є константа вибору, рівна значенню перемикача в момент виконання оператора. якщо такої константи вибору нема і присутнє слово else, то виконується оператор, що слідує за ключовим словом else. якщо ж гілка else відсутня і константи вибору нема, то ніякий оператор не виконується.
Приклад оператора вибору.
Нехай при тестуванні учень отримав N балів з 20 можливих. Треба вивести суму балів з коротким коментарем. Зробимо це за допомогою оператора case.
Програма оцінка;
Змінні
N : цілі;
Початок
Ввести( N );
Випадок N із
20:
ВивестиР('Краще не буває!');
19,18,17 :
ВивестиР('Відмінно!');
16,15,14,13 :
ВивестиР('Добре.');
12,11,10,9 :
ВивестиР('Задовільно.');
8,7 :
ВивестиР('Ще трохи, і все було б в порядку.');
інакше
ВивестиР('Як нічого не знаєте, то хоч би щось вгадали!')
кінець;
ВивестиР('Сума балів - ',N:2,' з 20 можливих');
кінець.


Цикл з параметром.

Оператор циклу з параметром викликає повторюване виконання оператора (що може бути складеним оператором) для всіх значень керуючої змінної в межах заданого діапазону.
For змінна := ПочЗн to КінЗн do
Оператор
Для змінна := ПочЗн до КінЗн виконати
Оператор

У якості керуючої змінної повинен використовуватися ідентифікатор, що позначає змінну, оголошену локальною в блоці, у якому міститься оператор for . Керуюча змінна повинна мати простий порядковий тип. Початкове і кінцеве значення повинні мати тип, сумісний по присвоюванню з порядковим типом.
Коли починає виконуватися оператор for , початкове і кінцеве значення визначаються один разів, і ці значення зберігаються протягом усього виконання оператора for . Оператор, що міститься у тілі оператора for , виконується один раз для кожного значення в діапазоні між початковим і кінцевим значенням. Керуюча змінна завжди ініціалізуться початковим значенням. При кожному наступному повторенні оператора for береться наступне значення керуючої змінної. якщо початкове значення перевищує кінцеве значення, то оператор , що міститься у тілі оператора for, не виконується. Коли в операторі циклу замість слова do використовується ключове слово downto ( внизДо ), значення керуючої змінної змінюються в зворотньому порядку. якщо початкове значення в цьому випадку менше, ніж кінцеве значення, то оператор не виконується.
Оператор, що міститься у тілі оператора for, не повинен змінювати значення керуючої змінної. Після виконання оператора for значення керуючої змінної стає невизначеним, якщо тільки виконання оператора for не було перервано за допомогою оператора переходу.
Приведемо приклади оператора циклу з параметром:
For sym := 'z' downto 'o' do
If str[i] = sym then GoTo 25;

For I := 1 to 10 do
For J := 1 to 10 do
Begin
X := 0;
For K := 1 to 10 do
X := X + Mat1[I,K]*Mat2[K,J];
Mat[I,J] := X;
end;


Цикл з післяумовою.

Оператор циклу з після-умовою записують в загальному вигляді так:
Repeat
оператор1;
........
операторN
until вираз

Повторювати
оператор1;
........
операторN
покиНе вираз

Операторів може бути довільна кількість, або не бути зовсім. Результат виразу повинен мати логічний тип. Оператори, поміщені між ключовими словами repeat і until, виконуються послідовно доти, поки результат виразу не прийме значення true. Послідовність операторів виконається принаймні один раз, оскільки обчислення виразу провадиться після виконання послідовності операторів.
Приведемо приклад оператора циклу з після-умовою:
repeat
K := I mod J;
I := J;
J := K;
until J = 0;


Цикл з передумовою.

Оператор циклу з перед-умовою містить у собі логічний вираз, який керує повторним виконанням оператора (що може бути складеним оператором).
While вираз dо
оператор

Поки вираз виконати
оператор

Вираз, за допомогою якого здійснюється керування повторенням оператора, повинен мати логічний тип. Обчислення його проводиться до того, як внутрішній оператор буде виконаний. Внутрішній оператор виконується повторно доти, поки вираз приймає значення false. якщо вираз із самого початку приймає значення false, то оператор, що міститься всередині оператора циклу з перед-умовою, не виконується.
Приклад оператора циклу з перед-умовою:
while Data[ I ] <> X do I := I + 1;


Звертання до процедури.

Оператор процедури активізує процедуру, позначену за допомогою ідентифікатора процедури. Якщо відповідний опис процедури містить список формальних параметрів, то оператор процедури повинен містити в собі відповідний йому список фактичних параметрів (параметри, список яких приводиться у визначенні, є формальними параметрами, а в операторі виклику процедури є фактичними параметрами). При виклику відбувається передача фактичних параметрів формальним параметрам.
Приведемо деякі приклади операторів процедур:
PrintHeaing;
Transpose(A,N,M);
Fin(Name,Address);


Формальні та фактичні параметри.

У описі процедури або функції задається список формальних параметрів. Кожний параметр, описаний у списку формальних параметрів, є локальним для модуля процедури або функції й на нього можна посилатися по його ідентифікатору.
Список формальних параметрів записується групами, які розділяються символом крапка з комою. Ідентифікатори кожної групи розділяються комою, після списку через двокрапку вказують ідентифікатор типу для даної групи.
Група параметрів, перед якими відсутнє ключове слово var, є списком параметрів-значень, група параметрів, перед якими міститься ключове слово var, є списком параметрів-змінних.
Формальний параметр-значення опрацьовується, як локальна стосовно процедури або функції змінна, за винятком того, що він отримує своє початкове значення із відповідного фактичного параметра при активізації процедури або функції. Зміни формального параметра-значення, не впливають на значення фактичного параметра.
Відповідне фактичне значення параметра-значення повинно бути виразом, який має тип, сумісний по присвоюванню з типом формального параметра-значення.
Параметр-змінна використовується, коли значення повинно передаватися з процедури або функції програмі , що її викликає. Відповідний фактичний параметр в операторі виклику процедури або функції повинен бути змінною. При активізації процедури або функції формальний параметр-змінна замінюється фактичною змінною, будь-які зміни в значенні формального параметра-змінної відбиваються на фактичному параметрі.
Усередині процедури або функції будь-яке посилання на формальний параметр-змінну приводить до доступу до самого фактичного параметра. Тип фактичного параметра повинен збігатися з типом формального параметра-змінної.
Якщо формальний параметр має рядковий тип, йому присвоюється атрибут довжини, рівний 255, і фактичний параметр повинний також мати рядковий тип і атрибут довжини, рівний 255.
Файловий тип може передаватися тільки, як параметр-змінна.
При посиланні на фактичний параметр-змінну, пов'язану з індексуванням масиву , ця дія виконуються перед активізацією процедури або функції.


Текстові файли. Ввід даних з клавіатури.

Будь-який файл, що складається з послідовності символів, можна представити у такому вигляді.

Бачимо, що файл є набором рядків тексту, кожен з яких закінчується спеціальним символом "кінець рядка". Весь файл закінчується символом "кінець файлу".
При відкриванні файлу для читання операційна система створює спеціальний вказівник, який показує наступний символ, який повинен бути прочитаний з файлу, і встановлює його на перший символ файлу. Зчитуючи кожен наступний символ, операційна система переставляє вказівник на наступний символ. Символи "кінець рядка" вводяться як будь-які інші, а спроба прочитати "кінець файлу" діагностується як помилка. Отже файл читається тільки посимвольно від початку до кінця, тобто є файлом послідовного доступу.
Аналогічно можна було б організувати введення з клавіатури. При звертанні до оператора Read система очікувала б натискання клавіш і вводила інформацію символ за символом. Але це незручно, бо випадково чи помилково натиснутий символ безпосередньо вводиться в програму, що позбавляє користувача можливості зробити виправлення.
Тому для введення даних з клавіатури передбачений спеціальний рядок символів, який називається буфером введення. При запуску програми на виконання буфер введення порожній. Коли зустрічається перший Read, виконання програми припиняється до тих пір, поки користувач не введе з клавіатури в буфер рядок символів, завершивши його натисканням Enter. До натискання цієї клавіші користувач може перевіряти і виправляти рядок. Виконання програми поновлюється, а ввід здійснюється з буфера до тих пір, поки не буде прочитаний останній символ, який міститься в ньому. Коли даних не вистачає, то система очікує вводу в буфер нового рядка. Таким чином - введення з клавіатури повністю аналогічно введенню з файлу, тільки при цьому кожний рядок вводиться користувачем.
Наприклад, якщо при виконанні фрагменту програми
Read ( a );
WriteLn ( 'A=', a );
Read ( b );
WriteLn ( 'B=', b );
ввести два числа одразу, то програма не очікуватиме вводу другого числа, а введе його з буфера, тобто у вікні виконання будемо бачити таке:
10 25
A = 10
B = 25


Опитування системного годинника.

Procedure Time ( var година, хвилина, секунда : integer );
Процедура присвоює фактичним параметрам, які мають бути цілими змінними, значення показів системного годинника в момент звертання до неї.
Параметри приймають такі значення:
година - від 0 до 23;
хвилина - від 0 до 59;
секунда - від 0 до 59.


Вивід інформації.

Write ( [ f : text ; ] v1 [, v2,...,vn] );
Вивести ( [ f : текст ; ] v1 [, v2,...,vn] );
Параметр f (якщо він наявний) є файловою змінною, яка відповідає текстовому файлу. Коли він пропущений, то процедура використовується для стандартного виводу на екран. Кожний параметр v є виразом, значення котрого повинно бути записане у файл чи виведене на екран. Кожний вираз повинний бути символьного, цілого, дійсного, текстового або логічного типу. В списку повинен бути хоча б один вираз.
Після кожного виразу можна вказувати мінімальну кількість символів, якою має бути записане виведене значення. Для цього після виразу ставиться двокрапка і записується вираз цілого типу, значання якого вказує кількість символів. якщо для значення, що виводиться, потрібно менше місця, то процедура дописує зліва необхідну кількість пробілів. Коли ж значення неможливо записати у вказаному полі, то воно записується мінімально можливою кількістю символів.
Дійсне значення записується у формі з плаваючою комою (+0.0000000Е+000). Мінімально можливе поле для нього – 7 символів. Можна виводити дійсні числа у формі з фіксованою комою. Для цього після відповідного виразу дійсного типу, значення якого треба вивести, вказують два числа, відділяючи кожне двокрапкою. При цьому перше означає загальну кількість позицій, яка має бути виділена для числа, а друге – кількість цифр після десяткової крапки.
При виводі логічного значення виконуються такі ж дії, як при записі рядків ‘Тruе’ або ‘false’, у залежності від значення виразу, який виводиться.
Процедура Write виводить всю інформацію в один нескінченно довгий рядок (виняток складає вивід символа “кінець рядка”). Це означає, що при наступному звертанні до вивід почнеться з того місця, на якому завершився попередній. Для переходу на новий рядок використовують процедуру WriteLn.
В ALGO екран завжди знаходиться в графічному режимі. Для запам’ятовування координат місця, в яке потрібно здійснювати вивід, існує так звана активна графічна позиція. При виводі кожного символа координата Х збільшується на ширину символа вибраного шрифта, а при виводі символа “кінець рядка” координата Х=0, а Y збільшується на висоту символа.


Вивід з переходом на новий рядок.

Write ( [ f : text ; ] v1 [, v2,...,vn] );
Вивести ( [ f : текст ; ] v1 [, v2,...,vn] );
Процедура виконує процедуру Write, а потім виводить символ кінця рядка. Коли виразів немає, то виводиться тільки символ кінця рядка.


Введення інформації.

Read ( [ f : text ; ] v1 [, v2,...,vn ] );
Ввести ( [ f : текст ; ] v1 [, v2,...,vn ] );
Параметр f (якщо він наявний) є файловою змінною, яка відповідає текстовому файлу. Коли він пропущений, то процедура використовується для стандартного вводу з клавітури. Кожний параметр v є змінною символьного, текстового, цілого або дійсного типу. Повинна бути хоча б одна змінна, значення якої треба прочитати.
У випадку символьного типу процедура Rеаd зчитує із файлу один символ і присвоює його змінній. Вказівник файлу переміщується на наступну позицію. Символ “кінець рядка” (Chr(13)) зчитується як звичайний символ. Коли поточна позиція у файлі вказує на символ “кінець файлу” або якщо файл не містить ніяких елементів, то видається повідомлення про помилку.
У випадку змінної цілого або дійсного типу процедура Rеаd зчитує з файлу послідовность символів, що утворять число, відповідно до синтаксису запису чисел. Вказівник файлу встановлюється на перший символ після числа. якщо числовий рядок не відповідає синтаксису, то виводиться повідомлення про помилку. У протилежному випадку змінній присвоюється значення прочитаного числа.
У випадку змінної текстового типу процедура Rеаd зчитує усі символи, аж до мітки кінця рядка (але не включаючи її), або до кінця файлу. Змінній присвоюється текстовий рядок, що утворився в результаті. якщо довжина результуючого рядка перевищує 255, то вона урізається. Вказівник файлу залишається на мітці кінця рядка. Тому для зчитування послідовності рядків не можна використовувати послідовного звертання до процедури Rеаd, оскільки при цьому ви ніколи не перейдете далі першого рядка. Після першого звертання до процедури Rеаd наступні операції Rеаd будуть виявляти мітку кінця рядка і повертати рядок нульової довжини. Тому для зчитування послідовності рядків використовуйте процедуру RеаdLn.


Приєднання файлу.

Procedude Assign( f : text ; name : string );
Процедура Приєднати( f : текст ; name : рядок );
Параметр f є файловою змінною типу текст, а є виразом текстового типу. Подальші операції з f будуть виконуватися з зовнішнім файлом з ім'ям, заданим параметром .
Ім'я складається з маршруту (шляху доступу), що визначає доступ до 0 або більш каталогів, імена яких відділені одне від одного за допомогою оберненої косої риски, за яким слідує справжнє ім'я файлу:
Диск:\ім'я_кат\ім'я_кат\...ім'я_кат\ім'я_файлу
Якщо шлях доступу починається з оберненої косої риски, то пошук починається в кореневому каталозі, у протилежному випадку він починається в поточному каталозі. Диск являє собою ідентифікатор диску (А-Z). якщо Диск і двокрапка будуть опущені, то використовується призначений по замовчуванню диск.
Параметр ім'я_файлу може містити саме ім'я, за яким можуть слідувати крапка і розширення імені файлу, довжиною до трьох символів.
Процедура Аssign не повинна використовуватися для відкритого файлу.


Опитування кінця рядка.

Function Eoln ( f : text ) : boolean;
Параметр f є файловою змінною, що визначає текстовий файл. якщо цей параметр опущений, то функція використовується для стандартного вводу з клавітури (натискання Enter вводить символ “кінець рядка”).
Якщо поточна позиція у файлі вказує на символ “кінець рядка”, то функція Еоln(f) повертає значення true. У протилежному випадку вона повертає значення false.


Закривання файлу.

Procedude Close ( f : text );
Процедура Закрити( f : текст );
Параметр f повинен бути файловою змінною типу текст. Відповідний файл має бути попередньо відкритий за допомогою процедур Rеset або Rеwrite. Для зовнішнього файлу, пов'язаного зі змінною f цілком виконується його відновлення і потім він закривається, після чого файловий канал операційної системи для даного файлу звільняється для наступного використання.


Опитування кінця файлу.

Function Eof ( f : text ) : boolean;
Параметр f є файловою змінною, що визначає текстовий файл. якщо цей параметр опущений, то функція використовується для стандартного вводу з клавітури (натискання Ctrl+Z вводить символ “кінець файлу”).
Коли поточна позиція у файлі вказує на символ “кінець файлу” або якщо файл не містить ніяких елементів, то функція Еоf(f) повертає значення true. У протилежному випадку вона повертає значення false.
Функцією Eof слід користуватись дуже акуратно при роботі з текстовими файлами. Дуже часто в літературі для роботи з нетипізованими файлами наводиться такий приклад:
while not Eof ( MyFile ) do
Begin
Read ( MyFile, alfa );
..................
end;
Для текстових файлів ця програма працюватиме правильно лише в тому випадку, коли символ "кінець файлу" слідує безпосередньо після останньої цифри останнього числа. Коли після останнього числа є пробіл або символ кінця рядка, то виконання циклу продовжиться і наступний оператор введення завершиться аварійно.


Ввід рядка.

ReadLn ( [ f : text ; ] v1 [, v2,...,vn ] );
ВвестиР ( [ f : текст ; ] v1 [, v2,...,vn ] );
Процедура виконується аналогічно до Read, але після присвоєння значень всім елементам списку змінних встановлює вказівник файлу на початок наступного рядка, пропускаючи всю інформацію до кінця поточного рядка.
Виклик функції ReadLn(f) без списку змінних приводить до переміщення поточної позиції файлу на початок наступного рядка (якщо вона є, у протилежному випадку відбувається перехід до кінця файлу). Просто запис ReadLn без параметрів очищує буфер вводу з клавіатури, якщо в ньому були символи, або очікує натискання клавіші Enter.
Коли для роботи програми потрібно вводити багато інформації, то доцільно створити текстовий файл і вводити інформацію з нього, а не з клавіатури. Для відлагодження програми її прийдеться виконувати багато разів і, коли нема файлу, щоразу вводити дані.
Наведемо приклад фрагменту програми, яка ілюструє ввід з текстового файлу.
Program апроксимація;
Var
ПочІнт, КінІнт : real;
КількТочок, ПорПолін, K : integer;
X, Y : array [1:10] of real;
Дані : text;
Begin
Assign( Дані, 'apr.dat' );
Reset( Дані );
ReadLn( Дані, ПочІнт );
ReadLn( Дані, КінІнт );
ReadLn( Дані, КількТочок );
ReadLn( Дані, ПорПолін );
for K:=1 to КількТочок do
ReadLn( Дані, X[K], Y[K] );
...........................

 Для її роботи потрібно підготувати файл apr.dat, можливий текст якого наведений далі. Зверніть увагу, що при процедура ReadLn ігнорує залишок рядка після вводу параметрів, які є у її списку. Ми використали це, щоб написати коментарі до чисел.
0.5 початок інтервалу
7.35 кінець інтервалу
7 кількість точок
5 порядок поліному
0.83 7.28 значення X,Y
1.33 5.07
2.28 10.25
4.27 1.25e-3
4.83 -3.85
5.01 -2.57
7.07 1.586


Відкривання файлу для читання.

Procedure Reset ( f : text );
Процедура Встановити ( f : текст );
Параметр f є файловою змінною. Він повинен бути пов'язаний із зовнішнім файлом за допомогою процедури Assign.
Процедура Reset відкриває існуючий зовнішній файл, ім'я якого було привласнено f . якщо зовнішній файл із зазначеним ім'ям відсутній, то це є помилкою. якщо файл f уже відкритий, то він спочатку закривається, а потім відкривається знову. Поточна позиція у файлі встановлюється на початок файлу. Текстовий файл стає доступним тільки для читання.


Відкривання файлу для запису.

Procedure Rewrite ( f : text );
Процедура Переписати ( f : текст );
Параметр f є файловою змінною. Він повинен бути пов'язаний із зовнішнім файлом за допомогою процедури Assign.
Процедура Reset створює новий зовнішній файл, ім'я якого було привласнено f . якщо зовнішній файл із зазначеним ім'ям вже існує, то він знищиться і на його місці створюється новий порожній файл. Файл стає доступним тільки для запису.


Опрацювання даних.

В цьому розділі описані функції, які реалізовані в ALGO як стандартні. Для користування ними не потрібно жодних додаткових описів.
Абсолютне значення.
Відкидання дробової частини.
Арктангенс.
Округлення.
Квадратний корінь.
Отримання символа за його кодом.
Перевірка на парність.
Наступне значення.
Попереднє значення.
Експонента.
Піднесення до квадрату.
Натуральний логарифм.
Число Пі.
Косинус.
Порядковий номер.
Генерування випадкових чисел.


Абсолютне значення.

Function Abs ( x );
Фактичним параметром має бути вираз дійсного або цілого типу.
Тип результату збігається з типом параметра. Результатом є модуль (абсолютне значення) х.


Відкидання дробової частини.

Function Trunc ( x : real ) : integer;
Функція перетворює значення дійсного типу до значення цілого типу шляхом відкидання дробової частини.


Арктангенс.

Function ArcTan ( x : real ) : real;
Фактичним параметром має бути вираз дійсного або цілого типу.
Результатом є головним значенням арктангенса x і має дійсний тип.


Округлення.

Function Round ( x : real ) :integer;
Функція Round округляє значення дійсного типу до значення цілого типу.


Квадратний корінь.

Function Sqrt ( x : real) : real;
Фактичним параметром має бути вираз дійсного або цілого типу.
Результатом є значенням квадратного кореня x і має дійсний тип.
Зауваження: якщо x < 0 видається повідомлення про помилку.


Отримання символа за його кодом.

Function Chr ( n : integer ) : char;
Фактичним параметром має бути вираз цілого типу, який задає порядковий номер символа в таблиці кодів.
Результатом є символ з номером n і має символьний тип.


Перевірка на парність.

Function Odd ( n : integer ) : boolean;
Фактичним параметром має бути вираз цілого типу.
Результат має логічний тип і рівний true, якщо n непарне, і false в протилежному випадку.


Наступне значення.

Function Succ ( n );
Фактичним параметром має бути вираз порядкового (boolean, char, integer) типу.
Тип результату збігається з типом параметра і має наступне після n значення в множині всіх значень типу.


Попереднє значення.

Function Pred(n);
Фактичним параметром має бути вираз порядкового (boolean, char, integer) типу.
Тип результату збігається з типом параметра і має попереднє перед n значення в множині всіх значень типу.


Експонента.

Function Exp ( x : real ) : real;
Фактичним параметром має бути вираз дійсного або цілого типу.
Результат має дійсний тип і є значенням експоненти x, тобто значення e підноситься до степені x (e=2.718281828459 - основа натурального логарифма).
Якщо x більше, ніж 700, то порядок результату більший за допустимий, тому програма діагностує помилку.


Піднесення до квадрату.

Function Sqr ( x : real );
Фактичним параметром має бути вираз дійсного або цілого типу.
Тип результату збігається з типом параметра. Результатом є квадрат х, тобто x*x.


Натуральний логарифм.

Function Ln ( x : real ) : real ;
Фактичним параметром має бути вираз дійсного або цілого типу.
Результатом є значенням натурального логарифма x і має дійсний тип.
Зауваження: якщо x <= 0 видається повідомлення про помилку.


Число Пі.

Function Pi: real;
Результат має дійсний тип і є значенням числа Pi (3,1415926535897932385).


Косинус.

Function Cos ( x : real ) : real;
Фактичним параметром має бути вираз дійсного або цілого типу, який задає кут в радіанах.
Результатом є значенням косинуса x і має дійсний тип.


Порядковий номер.

Function Ord ( n ) : integer;
Фактичним параметром має бути вираз порядкового (boolean, char, integer) типу.
Результатом є номер значення n в множині всіх значень типу і має цілий тип. Для цілого параметру результат завжди рівний n. Функція використовується для знаходження порядкового номера символа в таблиці кодів.


Генерування випадкових чисел.

Function Random ( x );
Фактичним параметром має бути вираз дійсного або цілого типу, який задає діапазон випадкових чисел.
Тип результату збігається з типом параметра. Результатом є випадкове число в діапазоні від [0 , x].
Зауваження: якщо функцію Random вживати без параметра, то результатом є дійсне випадкове число в діапазоні [0 , 1].


Опрацювання рядків тексту.

В цьому розділі описані функції та процедури, які реалізовані в ALGO як стандартні. Для користування ними не потрібно жодних додаткових описів.
Сполучення кількох текстових рядків.
Визначення довжини рядка.
Пошук зразка в рядку.
Копіювання частини рядка.
Видалення частини рядка.
Вставка одного рядка в інший.


Сполучення кількох текстових рядків.

Function Concat (s1, s2, ... : string) :string;
Функція повертає рядок, який є об'єднанням всіх значень зі списку формальних параметрів.
Якщо довжина утвореного рядка більша ніж 255, то зайві символи ігноруються.
Приклад:
для рядкових змінних S, S1, S2, S3 запис
S := Concat( S1, S2, S3 );
тотожний запису
S := S1 + S2 + S3;


Визначення довжини рядка.

Function Length ( s : string ) :integer;
Параметр s є виразом текстового типу. Результатом буде довжина s.
Приклад:
в результаті виконання фрагменту програми
S := 'Наше місто';
N := Length ( S );
N набуде значення 10.


Пошук зразка в рядку.

Function Pos ( s1, s : string ) :integer;
Параметри s1 і s є виразами текстового типу. Дана функція шукає зразок, заданий параметром s1, у рядку s і повертає ціле значення, що є позицією першого символу s1 в рядку s. Якщо зразок не знайдений, то функція повертає значення 0.
Приклад:
наступний фрагмент програми замінить пробіли нулями
S := '1 23 5 6';
while Pos (' ',S) > 0 do
S[ Pos (' ',S)] := '0';
i S отримає значення '10230506'.


Копіювання частини рядка.

Function Copy ( s : string; n, k : integer ) : string;
Функція повертає рядок з k символів, який починається із n-го символу рядка s .
Якщо значення параметра n перевищує довжину рядка, то повертається порожній рядок. Якщо параметр k задає більше символів, ніж залишається в рядку, починаючи із символу n, то повертається тільки залишок рядка.
Приклад:
в результаті виконання фрагменту програми
s := 'ABCDEF';
s := Copy(s,2,3);
s набуде значення 'BCD'.


Видалення частини рядка.

Procedude Delete ( var s : string; n ,k : integer );
Процедура видаляє k символів з текстового рядка s, починаючи із n-го символу.
Якщо значення параметра n перевищує довжину рядка, то символи не видаляються. Якщо параметр k задає більше символів, ніж залишається в рядку, починаючи із символу n, то видаляється тільки залишок рядка.
Приклад:
в результаті виконання фрагменту програми
s := 'ABCDEF';
Delete(s,2,3);
s набуде значення 'AEF'.


Вставка одного рядка в інший.

Procedure Insert(s1 : string; var s : string; n : integer);
Параметр s1 являє собою вираз текстового типу. Параметр s - змінна текстового типу будь-якої довжини. Параметр n є виразом цілого типу. Дана процедура вставляє рядок, що задається параметром s1, у рядок, що задається параметром s, починаючи з позиції n. якщо рядок , що утворився в результаті , перевищує 255 символів, то він обрізається до 255 символів.
Приклад:
в результаті виконання фрагменту програми
s := 'Наше місто';
Insert('гарне ',s,6);
s набуде значення 'Наше гарне місто'.


Різні процедури.

В цьому розділі описані функції та процедури, які реалізовані в ALGO як стандартні. Для користування ними не потрібно жодних додаткових описів.
Опитування дати.
Опитування наявності повідомлення.
Опрацювання повідомлення про подію.
Часова затримка.
Звукові файли.


Опитування дати.

Procedude Date ( var рік, місяць, день : integer );
Процедура присвоює фактичним параметрам, які мають бути цілими змінними, значення показів системного годинника в момент звертання до неї.
Параметри приймають такі значення:
рік – 1999, 2000;
місяць - від 1 до 12;
день - від 1 до 31.


Опитування наявності повідомлення.

Function IsEvent : boolean;
Функція повертає логічне значення true, якщо від моменту початку виконання програми або останнього звертання до процедури Event відбулася подія і false в протилежному випадку. Подією вважається натискання довільної клавіші на клавіатурі або натискання мишки у вікні виконання.


Опрацювання повідомлення про подію.

Procedure Event ( var k, x, y :integer);
Подією вважається натискання довільної клавіші на клавіатурі або натискання мишки у вікні виконання. ALGO фіксує факт настання події та запам'ятовує останню подію для її обробки. При настанні наступної події інформація про попередню втрачається. Процедура обнулює признак наявності події та присвоює фактичним параметрам, які повинні бути змінними цілого типу, такі значення.
При натисканні клавіші:
k = 1;
x - код клавіші
y - інформація про стан службових клавіш.
При натисканні кнопки мишки:
k = 2;
x – координата x;
y – координата y.
Коли на момент звертання до процедури подія ще не відбулася, процедура очікує події, про що вказуєтья у вікні режиму роботи ALGO.
Приклад.
Наступна програма малює лінію до точки при натисканні кнопки мишки або виводить код натисненої клавіші до тих пір, поки не буде натиснена клавіша Esc.
Program test;
var
i,j,k:integer;
Begin
Repeat
Event(i,j,k);
Case i of
1 : Write(j);
2 : LineTo(j,k);
end
until (i=1) and (j=27)
end.


Часова затримка.

Procedure Delay ( ms : integer );
Параметр ms повинен бути виразом цілого типу і задає число мілісекунд інтервалу чекання. Дана процедура є приблизною, тому період затримки не буде точно рівний заданому числу мілісекунд.


Звукові файли.

Щоб озвучити записанй у файлі з розширенням .wav звук, треба звернутись до процедури
Procedure PlaySound ( n : integer ; name : string );
Процедура Озвучити ( n : цілі ; name : рядки );
 де n - режим відтворення звуку, а name - повне ім'я звукового файлу. Залежно від значення параметра n можливі такі режими відтворення:
0 - система вмикає відтворення звуку і припиняє подальше виконання програми до його завершення;
1 - система вмикає відтворення звуку і продовжує виконувати програму, не очікуючи його завершення. Коли системні ресурси на цей час зайняті відтворенням іншого звуку, то програма очікує їх звільнення;
2 - так само, як в попередньому пункті, але система примусово звільнює системні ресурси для відтворення заданого звуку;
3 - циклічне (нескінченне) повторення заданого звуку. Увага! Цим режимом треба користуватись дуже обережно. Коли Ви не завершите відтворення звуку примусово, то він триватиме, поки не завершити роботу ALGO;
4 - зупинка відтворення заданого файлу. Коли name - порожній рядок, то негайно завершується відтворення всіх звуків;


Процедури для побудови графічних зображень.

Графічний екран.
Встановлення кольору тексту.
Встановлення поточних координат.
Побудова прямокутника.
Поточні координати та кольoри.
Побудова еліпса.
Зафарбування замкнених областей.
Витирання вікна виведення.
Крапка.
Проведення лінії між точками.
Вибір типу і кольору ліній.
Проведення лінії до точки.
Вибір стилю заповнення.
Вибір шрифта.


Графічний екран.

Для відображення інформації в середовищі ALGO виділено робоче поле розміром 800 точок по горизонталі та 600 точок по вертикалі. Частина цього поля видно у вікні виводу. За допомогою вертикального та горизонтального повзунків можна переглядати весь графічний екран.

як видно з наведеного малюнка, початком координат вважають верхній лівий куток екрану. Вісь Х направлена зліва направо, Y - зверху вниз. Для всіх графічних функцій координати задають в формі (X,Y).
якщо координати при побудові зображення виходять за межі графічного екрану, то інформація поза межами екрану ігнорується. Виняток становлять оператори readln та writeln. При спробі виводу за нижню межу екрану все зображення на екрані посувається вверх на величину висоти символа.


Встановлення кольору тексту.

Активний (поточний) колір тексту встановлюють за допомогою звертання до процедури textColor, яка оголошена наступним чином
Procedure TextColor ( r, g, b : integer);
Процедура КолірТексту ( r, g, b : цілі );
 де r, g, b - задають частки червоного,зеленого та синього в результуючому кольорі тексту. Встановленим кольором буде відображатись уся текстова інформація, яка виводиться на екран процедурами read та write. Фактичними параметрами при звертанні до процедури TextColor мають бути змінні, константи чи вирази цілого типу, значення яких знаходиться в діапазоні 0 -:- 255.
По замовчуванню встановлений чорний колір тексту (0,0,0).
Приклад:
в результаті виконання фрагменту програми
TextColor ( 200, 0, 0);
WriteLn ('Червоний текст');
TextColor ( 0, 0, 255);
WriteLn ('Синій текст');
отримаємо такий результат
Червоний текст
Синій текст


Встановлення поточних координат.

Активна графічна позиція встановлюється в точку з координатами x,y процедурою MoveTo, яка оголошена наступним чином
Procedure MoveTo ( x, y : integer) ;
Процедура Перемістити ( x, y : цілі );
 Активну графічну позицію використовують процедури:
LineTo та Write.


Побудова прямокутника.

Прямокутник будують за допомогою звертання до стандартної процедури rectangle, яка оголошена наступним чином
Procedure Rectangle ( x1, y1, x2, y2 : integer);
Процедура Прямокутник ( x1, y1, x2, y2 : цілі );
 де x1,y1 та x2,y2 - координати двох діаметрально протилежних вершин прямокутника. Фактичними параметрами при звертанні до процедури rectangle мають бути змінні, константи чи вирази цілого типу.
Прямокуткик буде побудований активним олівцем та зафарбований активним кольором пензля, або не зафарбований, якщо встановлений прозорий колір пензля.
Після виконання процедури активна графічна позиція встановлюється в точку з координатами x2,y2.
Приклад:
в результаті виконання фрагменту програми
rectangle ( 30, 30, 90, 60 );
rectangle ( 10, 90, 60, 10);
отримаємо такі прямокутники


Поточні координати та кольoри.

При виводі текстової чи графічної інформації на екран необхідно вказати, куди саме виводити: зверху, посередині чи внизу, а також колір тексту, ліній та заповнення. Вказувати цю інформацію в кожному операторі було б дуже незручно. Тому система запам'ятовує значення координат точки, в якій завершився вивід інформації та параметри вибраних інструментів. Ці значення називають активними. При запуску програми встановлюються нульові координати (верхній лівий куток екрану), чорний олівець одиничної товщини та чорний колір тексту. Колір заповнення замкнених фігур (колір пензля) вибирається прозорий, тобто замкнені фігури не зафарбовуються.
В процесі роботи програми активні координати міняються так,щоб наступний вивід здійснювався там, де закінчився попередній.
Активні координати міняють такі процедури MoveTo, LineTo, Line, Rectangle, Write,WriteLn, Point, Clear, а використовують процедури LineTo, Write, WriteLn
Активні кольори встановлюють процедурами: Pen, TextColor, Brush
Приклад:
в результаті виконання фрагменту програми
Write('ПОЧАТОК');
LineTo(30,60);
Write('КІНЕЦЬ');
LineTo(0,60);
отримаємо такий результат


Побудова еліпса.

Еліпс будують за допомогою звертання до стандартної процедури ellipse, яка оголошена наступним чином
Procedure Ellipse ( x1, y1, x2, y2 : integer );
Процедура Еліпс ( x1, y1, x2, y2 : цілі );
 де x1, y1 та x2, y2 - координати двох діаметрально протилежних вершин прямокутника, в який вписується еліпс. Фактичними параметрами при звертанні до процедури ellipse мають бути змінні, константи чи вирази цілого типу.
Еліпс буде побудований активним олівцем та зафарбований активним пензликом, або не зафарбований, якщо встановлений прозорий колір пензлика.
Після виконання процедури активна графічна позиція не змінюється
Приклад:
в результаті виконання фрагменту програми
ellipse ( 0, 0,90,60);
ellipse (30,30,60,90);
отримаємо такі еліпси


Зафарбування замкнених областей.

Щоб зафарбувати замкнену область, треба звернутись до процедури Fill, яка оголошена наступним чином
Procedure Fill ( x, y : integer );
Процедура Зафарбувати ( x, y : цілі );
 Фактичними параметрами при звертанні до процедури Fill мають бути змінні, константи чи вирази цілого типу.
Починаючи з точки з координатами x,y, процедура заповнює екран у всіх напрямках активним кольором заповнення до тих пір, поки не зустрінеться межа іншого кольору, ніж колір вказаної точки. Іншими словами процедура Fill міняє колір замкненої області, всередині якої лежить точка (x,y) на активний колір заповнення, який встановлюють процедурою Brush.
Процедура Fill не виконує ніяких дій, якщо заданий прозорий колір заповнення або колір точки (x,y) співпадає з кольором заповнення.


Витирання вікна виведення.

Для витирання вікна результатів використовують процедуру clear ( витерти ).
Крім витирання вікна, процедура виконує натупні дії:
встановлює чорний олівець товщиною 1;
встановлює чорний колір тексту;
встановлює прозорий колір заповнення;
встановлює активну графічну позицію - ( 0, 0);
встановлює активний шрифт - (8,0,400).


Крапка.

Щоб поставити (намалювати) крапку в позиції з координатами x,y, треба звернутись до процедури Point, яка оголошена наступним чином
Procedure Point ( x, y : integer );
Процедура Крапка ( x, y : цілі );
 Фактичними параметрами при звертанні до процедури Point мають бути змінні, константи чи вирази цілого типу.
Колір крапки визначається активним кольором ліній.
Після виконання процедури активна графічна позиція встановлюється в точку з координатами x,y.


Проведення лінії між точками.

Лінію проводять за допомогою звертання до стандартної процедури line, яка оголошена наступним чином
Procedure Line ( x1, y1, x2, y2 : integer );
Процедура Лінія ( x1, y1, x2, y2 : цілі );
 де x1,y1 та x2,y2 - координати двох кінців лінії. Фактичними параметрами при звертанні до процедури line мають бути змінні, константи чи вирази цілого типу.
Лінія буде проведена вибраним олівцем.
Після виконання процедури активна графічна позиція встановлюється в точку з координатами x2,y2.
Приклад:
в результаті виконання фрагменту програми
line ( 30, 30, 90, 60 );
line ( 10, 90, 60, 10);
отримаємо такі лінії

Лінію проводять також процедурою LineTo.


Вибір типу і кольору ліній.

Активний (поточний) колір та товщину ліній встановлюють, вибираючи відповідний оцівець за допомогою процедури
Procedure Pen ( n, r, g, b : integer );
Процедура Олівець ( n, r, g, b : цілі );
 де n вказує товщину лінії в пікселах, а r, g, b - задають частки червоного,зеленого та синього в результуючому кольорі ліній. Встановленим кольором будуть відображатись усі лінії , які виводяться на екран процедурами LineTo, Line, Rectangle, Ellipse, Point. Фактичними параметрами при звертанні до процедури Pen мають бути змінні, константи чи вирази цілого типу, значення яких знаходиться в діапазоні 0 -:- 255.
По замовчуванню встановлений чорний колір ліній (0,0,0) і одинична товщина.


Проведення лінії до точки.

Коли наступна лінія починається з кінця попередньої, якбуває при побудові ламаних ліній чи графіків, зручно користуватисьпроцедурою LineTo, яка оголошена наступним чином
Procedure LineTo ( x, y : integer );
Процедура ЛініяДо ( x, y : цілі );
 де x,y - координати кінця лінії. Лінія починається з активної графічної позиції.Фактичними параметрами при звертанні до процедури LineTo мають бути змінні, константи чи вирази цілого типу.
Лінія буде проведена вибраним олівцем.
Після виконання процедури активна графічна позиція встановлюється в точку з координатами x,y.
Приклад:
в результаті виконання фрагменту програми
LineTo ( 30, 30 );
LineTo ( 10, 90 );
LineTo ( 60, 90 );
отримаємо такі лінії

Активну графічну позицію міняють процедурою MoveTo.
Лінію проводять також процедурою Line.


Вибір стилю заповнення.

Активний (поточний) колір заповнення встановлюють за допомогою звертання до процедури Brush, яка оголошена наступним чином
procedure Brush ( k, r, g, b : integer );
процедура Пензлик ( k, r, g, b : цілі );
 де r, g, b - задають частки червоного,зеленого та синього в результуючому кольорі заповнення, а параметр k задає стиль заповнення. Якщо k=1 то замкнені фігури зафарбовуються, а при k=0 встановлюється так званий прозорий колір заповнення, тобто фігури не зафарбовуються. Встановленим кольором будуть зафарбовуватись фігури процедурами Rectangle, Ellipse та Fill. Фактичними параметрами при звертанні до процедури Brush мають бути змінні, константи чи вирази цілого типу, значення яких знаходиться в діапазоні 0 -:- 255.
В залежності від типу монітора операційна система може використовувати для заповнення суміш кольорів. В цьому випадку процедура Fill може працювати екоректно. Для отримання чистих кольорів в цьому випадку треба задавати значення r, g, b такі, щоб остача від ділення їх на 8 була рівна 7.
Приклад:
в результаті виконання програми
Програма кольори;
початок
Олівець(1,255,0,0);
Прямокутник(0,0,60,60);
Олівець(1,0,0,255);
Пензлик(1,0,255,0);
Прямокутник(30,30,90,90);
Олівець(1,255,0,255);
Пензлик(0,0,0,0);
Еліпс(10,10,80,80);
кінець.
 отримаємо такий результат


Вибір шрифта.

Активний (поточний) шрифт для виведення тексту встановлюють за допомогою звертання до процедури font, яка оголошена наступним чином
Procedure Font ( h, a, b : integer );
Процедура Шрифт ( h, a, b : цілі );
 де h, a, b - задають висоту пікселах, кут нахилу в градусах та насиченість тексту. Насиченість задають числом з діапазону 0 -:- 1000. При цьому звичайний шрифт має насиченість 400, а жирний - 600. Встановленим шрифтом буде відображатись уся текстова інформація, яка виводиться на екран процедурами read та write. Фактичними параметрами при звертанні до процедури font мають бути змінні, константи чи вирази цілого типу.
По замовчуванню встановлений шрифт (8,0,400).
Зауваження: для коректної роботи при виведенні нахиленого тексту треба перед оператором виведення встановлювати графічну позицію, а в списку виводу вказувати лише одне значення.
Приклад:
в результаті виконання фрагменту програми
WriteLn('Горизонтальний текст');
MoveTo(0,100);
Font(30,30,800);
WriteLn('Нахилений текст');
отримаємо такий результат


Можливості робота та керування ним.

Робот-вантажник зображений у вигляді маленького вантажного автомобіля. Він може рухатися тільки по вертикалі або по горизонталі. Крок переміщення - одна клітинка складу.При запуску програми встановлюються одиничні координати (верхній лівий куток ) та напрям вниз.

Робот може:
- переміщуватись по командах Вперед і Назад;
- повертатися по командах Наліво і Направо;
- опитувати вільний шлях по командах ВільноПопереду, ВільноПозаду, ВільноЗліва,ВільноСправа;
- опитувати обстановку попереду по команді Локатор;
- працювати з вантажами по командах Взяти і Покласти;
- помічати клітинки по команнді Помітити і опитувати, чи Помічена клітинка;
- повідомити свої координати по команді Координати та напрям руху по команді Напрям.
- повідомити, чи Порожній робот.


Рух назад.

Для того, щоб робот рухався назад, треба звернутись до процедури Назад, яка оголошена наступним чином
procedure Backward ( x : integer );
процедура Назад ( x : цілі );
 де x - кількість клітинок, на яку повинен переміститися робот.
Якщо кількість клітинок не вказана, то робот переміщується на одну клітинку назад. При цьому дужки вживати не можна.
Рух здійснюється в напрямку, протилежному до того, в якому орієнтований робот в момент звертання до процедури.
Якщо на шляху зустрічається стіна або вантаж, то видається повідомлення про помилку.
Приклад:
фгагмент програми
for i:=1 to 10 do
Backward ;
еквівалентний команді
Backward ( 10 );


Рух вперед.

Для того, щоб робот рухався вперед, треба звернутись до процедури вперед, яка оголошена наступним чином
Procedure Forward ( n : integer );
Процедура Вперед ( n : цілі );
 де n - кількість клітинок, на яку повинен переміститися робот.
Якщо кількість клітинок не вказана, то робот переміщується на одну клітинку вперед. При цьому дужки вживати не можна.
Рух здійснюється в тому напрямку, в якому орієнтований робот в момент звертання до процедури.
Якщо на шляху зустрічається стіна або вантаж, то видається повідомлення про помилку.
Приклад:
фгагмент програми
for i:=1 to 10 do
Forward ;
еквівалентний команді
Forward ( 10 );


Поворот ліворуч.

Для того, щоб робот повернувся ліворуч, треба звернутись до процедури Наліво, яка оголошена наступним чином
Procedure Left ( x : integer );
Процедура Наліво ( x : цілі );
 Якщо аргумент не вказаний, то робот повертається на 90 градусів ліворуч. При цьому дужки вживати не можна. Якщо вказати аргументом ціле додатнє число, то поворот повторюється задане число разів.
Зверніть увагу, що напрям повороту задається відносно робота, а не відносно спостерігача.

Приклад:
команда
Left ( 3 );
еквівалентна команді
Right ;


Опитування обстановки попереду.

Для детального опитування обстановки перед роботом треба звернутися до функції локатор, яка оголошена наступним чином
Function InFront : integer;
Функція Локатор : цілі;
 В залежності від ситуації в напрямку руху робота функція повертає таке значення:
0 - перед роботом стіна;
+1 - перед роботом вантаж;
+2 - перед роботом вихід;
-N - перед роботом N вільних клітикок;


Помітити клітинку.

В багатьох задачах виникає необхідність якось помічати клітинки. Наприклад, при пошуку виходу з лабіринту, в якому є замкнені шляхи. Робот може помітити клітинку, на якій він знаходиться, маленьким прапорцем. Для цього треба викликати процедуру
Procedure Select;
Процедура Помітити;
 Якщо клітинка вже була помічена, то команда ігнорується роботом.
Помічені клітинки розпізнаються командою помічено і витираються командою СтертиМітку.
Приклад:
в результаті виконання фрагменту програми
Для номер := 1 до 10 виконати
Початок
Якщо номер mod 2 = 0 то Помітити;
Вперед;
кінець;
робот помітить парні клітинки


Опитування вільного шляху.

При переміщенні в невідомій обстановці робот мусить контролювати за допомогою сенсорів, чи вільна клітинка в заданому напрямку. Інакше він може розбитися до стіни чи розчавити вантаж. Сенсори активізуються при виклику логічних функцій
ВільноПопереду, ВільноПозаду, ВільноЗліва, ВільноСправа;
FreeForw, FreeBack, FreeLeft, FreeRight.
 Ці функції не мають параметрів і повертають істинне значення ( true ), якщо клітинка у відповідному напрямку вільна або помічена, і хибне значення ( false ), якщо у відповідному напрямку вантаж або стіна.
Зверніть увагу, що напрям опитування задається відносно робота, а не відносно спостерігача.

Приклад:
в результаті виконання фрагменту програми
While FreeForward do
Forward ;
робот буде рухатися вперед, поки не зустріне перешкоду (вантаж або стіну).


Стирання мітки.

Для стирання мітки треба викликати процедуру
Procedure Unselect;
Процедура СтертиМітку;
 Якщо клітинка не була помічена, то команда ігнорується роботом.
Мітки розпізнаються командою помічено і ставляться командою помітити.


Опитування мітки.

Робот може помітити клітинки маленькими прапорцями. Для опитування мітки звертаються до логічної функції
Function Selected : boolean;
Функція Помічено : логічні;
 Функція повертає істинне значення ( true ), якщо клітинка, на якій знаходиться робот, помічена, і хибне значення ( false ) в протилежному випадку.
Приклад:
в результаті виконання фрагменту програми
While FreeForward and not selected do
Forward ;
робот буде йти вперед, поки не зустріне перешкоду або помічену клітинку. Зверніть увагу, що робот зупиниться на поміченій клітинці, але перед перешкодою.


Взяти вантаж.

Для того, щоб взяти вантаж треба викликати процедуру
Procedure Take;
Процедура Взяти;
 По команді Взяти робот бере, як справжній автонавантажувач, вантаж, який знаходиться на клітинці безпосередньо перед ним. Якщо вантажу немає або робот вже завантажений, то видається повідомлення про помилку.


Визначення напряму руху.

Всі команди робота враховують його орієнтацію. Якщо виникає необхідність визначити орієнтацію робота відносно спостерігача, треба звернутися до функції напрям, яка оголошена наступним чином
Function Direction : integer;
Функція Напрям : цілі;
 В залежності від орієнтації робота функція повертає таке значення:
0 - робот направлений вниз (на південь);
1 - робот направлений вправо (на схід);
2 - робот направлений вверх (на північ);
3 - робот направлений вліво (на захід);


Чи завантажений робот.

Робот може взяти вантаж тільки в тому випадку, коли він не завантажений, і покласти вантаж, коли він везе його. Щоб перевірити, чи робот порожній, звертаються до логічної функції
Function Empty : boolean;
Функція Порожній : логічні;
 Функція повертає істинне значення ( true ), якщо робот не завантажений і хибне значення ( false ) в протилежному випадку.


Опитування поточних координат.

Поточні координати робота можна визначити, викликавши процедуру Координати, яка оголошена наступним чином
Procedure Coordinates ( var x, y : integer );
Процедура Координати ( змінні x, y : цілі );
 Після виконання процедури змінній x присвоюється значення номера стовпця, а змінній y - номера рядка, на перетині яких знаходиться робот. Нумерація рядків ведеться зверху вниз, а нумерація стовпців - зліва направо, як показано на малюнку.


Запис інформації про склад у файлі.

В простих програмах робот їздить по складі, опитує обстановку, переміщує вантажі. Однак це не є прикладом ефективного програмування поведінки робота. Справді, для того,щоб відшукати вихід з лабіринту чи знайти і привезти вантаж зовсім не потрібно ганяти робота по всіх закутках і тупиках складу. Адже робот насправді може бути багатотонним самохідним автонавантажувачем і на пошук шляху витратить непомірну кількість палива чи енергії!
Набагато краще, якщо програма на основі інформації про склад сформує для робота послідовність команд, які приводять до поставленої мети найкоротшим шляхом. Однак для цього необхідно мати цю інформацію.
В програмі відсутні засоби отримання інформації про стан всього складу, однак програміст, який вже має достатні знання для рішення таких задач, може отримати схему складу, прочитавши її з файлу.
Інформація про склад записується в текстовому файлі з розширенням .maz. В файлі міститься 15 рядків по 20 символів в кожному. Перші та останні рядки та стовпчики (по периметру складу) змінювати не можна. При читанні файлу програмою вони ігноруються.
Символи мають такий зміст:
w - в клітинці стіна;
b - в клітинці вантаж;
s - клітинка помічена;
. - клітинка вільна;
цифра 0-3 - в кітинці робот, направлений у відповідному напрямі.
Наведемо приклад програми читання файлу.
Program LoadMaze;
Type
maze=array[0:14,0:19] of char;
Var
test:maze;
i,j:integer;
Procedure load;
Var
fm:text;
Begin
Assign(fm,'left.maz');
Reset(fm);
For i:=0 to 14 do
Begin
For j:=0 to 19 do
Read(fm,test[i][j]);
ReadLn(fm);
end;
Close(fm);
end;
Begin
load;
..................


Покласти вантаж.

Для того, щоб робот поклав вантаж треба викликати процедуру
Procedure Put;
Процедура Покласти;
 По команді Покласти робот кладе, як справжній автонавантажувач, вантаж, на клітинку безпосередньо перед ним. Якщо вантажу робот не завантажений або клітинка перед ним не вільна, то видається повідомлення про помилку. Якщо клітинка, на яку кладуть вантаж, помічена, то мітка витирається.


Приклади простих програм.

В цьому розділі будуть наведені приклади програм, які ілюструють виконання окремих операторів, використання стандартних функцій та процедур. Вибачте, розділ ще не підготовлений. Тимчасово в розділ поміщені приклади програм з підручника А.Ф.Верлань, Н.В.Апатова "Інформатика" . E1 E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12 E13 E14 E15 E16 E17 E18 E19 E20 E21 E22 E23 E24 E25 E26 E27 E28 E29 E30 E31 E32 E33 E34 E35 E36 E37 E38 E39 E40 E41 E42 E43 E44


Приклади складних програм.

В цьому розділі подані приклади складних програм, для написання яких використовуються різні оператори.


Проста навчальна програма.

Табличку множення треба знати. Напам'ять. Незважаючи на наявність калькулятора в кишені кожного учня. Але усвідомлення цього прикрого факту приходить значно пізніше, а в школі вчитель мусить примусити вивчити цю табличку. Давайте полегшимо його працю і розробимо програму, яка буде перевіряти знання цієї сумнозвісної таблички.
Алгоритм дуже простий. Щоб пересвідчитись, що учень знає табличку множення, задаємо йому десять запитань. Для кожного запитання випадковим чином вибираємо два числа множ1 та множ2 і запитуємо відповідь. Якщо відповідь не співпадає з добутком множників, то оцінку зменшуємо на один бал.
Для оцінювання використаємо десятибальну шкалу. Початкове значення оцінки - 10. Але оцінку 7 в журнал не поставиш! Тому при виводі нашу десятибальну оцінку ділимо на два.
Для вибору чисел використаємо функцію генерування випадкових чисел. Функція random(N) повертає випадкове число з діапазону 0..N. Щоб не задавати учневі тривіальних завдань множення на нуль та одиницю, будемо вибирати числа з діапазону 0..7 і збільшувати їх на 2. При цьому значення множників будуть в діапазоні 2..9. Тепер цей словесний опис запишемо мовою Паскаль.
Програма ТаблицяМноження;
Змінні
множ1,множ2,добуток,відповідь,оцінка,питання:цілі;
Початок
оцінка:=10;
Для питання:=1 до 10 виконати
Початок
множ1:=random(7)+2;
множ2:=random(7)+2;
добуток:=множ1*множ2;
Вивести(множ1:1,'*',множ2:1,'=');
Ввести(відповідь);
Якщо відповідь<>добуток то
оцінка:=оцінка-1;
кінець;
Вивести('оцінка ',оцінка div 2:2)
кінець.
 Все дуже просто. Навіть примітивно. Але так само примітивно ця програма працює. Задавши питання, вона необмежено довго очікує на відповідь. За цей час можна порахувати на пальцях, запитати в мудрого товариша чи збігати додому і запитати в мами. Але жартувати тут не можна, бо табличка множення - справа серйозна.
Потрібно зробити так, щоб машина очікувала відповіді протягом обмеженого часу. Якщо за цей час відповіді нема, то, очевидно, учень не знає. Треба також якимось чином показувати, як зменшується час очікування і скільки ще можна думати. Таким чином, програма мусить не просто чекати на відповідь, але виконувати в цей час якісь дії (виводити інформацію про час на обдумування). Це означає, що використати оператор Ввести(відповідь) ми не можемо, бо поки не завершиться його робота, ніякі інші оператори програми виконуватись не можуть.
Для того, щоб знайти шлях вирішення поставленої проблеми, треба зрозуміти принцип роботи програми в операційній системі. Всі зовнішні втручання (натискання клавіш, переміщення мишки і т.д.) називаються подіями. Інформація про події поступає не прикладній програмі, а операційній системі. ОС аналізує подію і формує повідомлення про неї, в якому вказано тип події, якій конкретній програмі подія адресована та деякі інші параметри (код натиснутої клавіші або координати вказівника мишки). Для кожної програми, яка працює в ОС, резервується спеціальна ділянка пам'яті, в яку ОС записує повідомлення про події, які повинна проаналізувати дана програма.
У всіх мовах програмування є стандартні функції, які дозволяють опитати, чи є повідомлення для програми, і ввести параметри цих повідомлень. Щоб перевірити, чи є якесь повідомлення для нашої програми, будемо використовувати логічну функцію ЄПодія, а для введення інформації про подію - процедуру Подія(тип,пар1,пар2). Процедура надає змінній тип значення 1, якщо натиснута клавіша, і значення 2, якщо натиснута кнопка мишки. В першому випадку пар1 - код натиснутої клавіші, а в другому - пар1,пар2 - координати мишки.
Розглянемо це туманне пояснення на прикладі. Нехай потрібно написати функцію, яка протягом 5 секунд очікує натискання клавіші. Якщо за вказаний час клавіша натиснена, то функція повертає значення натиснутої цифри, в ішших випадках - значення -1. Намалюємо зелений прямокутник шириною 300 пікселів, який буде показувати час, відведений на очікування. Опишемо цілу змінну ширина і надамо їй початкове значення 0. Намалюємо червоний прямокутник шириною ширина, який буде показувати час, що вже минув. Можна зробити, щоб червоний прямокутник закривав зелений, хоч це і не обов'язково. Якщо збільшувати змінну ширина з заданим кроком в циклі і щоразу перемальовувати червоний прямокутник, то він в результаті цього буде "рости", показуючи, як спливає час.
При кожному повторенні циклу треба перевірити, чи не була натиснута клавіша. Іншими словами, цикл завершується коли натиснута клавіша або завершився час очікування (ширина червоного прямокутника стала більша за 300). Швидкість "росту" червоного прямокутника регулюємо процедурою Затримка, яка робить паузу при кожному виконанні циклу.
Якщо цикл завершився, бо учень вчасно ввів відповідь, то знаходимо значення введеної цифри і присвоюємо його імені функції для передачі в головну програму. В протилежному випадку (коли час очікування завершився), повертаємо -1.
Функція результат:цілі;
Змінні
ширина,i,j,k:цілі;
Початок
ширина:=0;
Пензлик(1,0,255,0);
Прямокутник(10,50,310,70);
Пензлик(1,255,0,0);
Поки (не ЄПодія) та (ширина<300) виконати
Початок { цикл очікування натискання клавіші }
Прямокутник(10,50,10+ширина,70);
Затримка(10);
ширина:=ширина+10
кінець;
Якщо ширина<300 то
Початок { клавіша натиснена вчасно }
Подія(i,j,k);
Якщо (j>47) та (j<59) то
результат:=j-48 { клавіша цифрова }
інакше результат:=-1 { інша клавіша }
кінець
інакше { час очікування закінчився }
результат:=-1;
Пензлик(1,255,255,255)
кінець;
Отака проста функція вводить одноцифрові числа. Для таблички множення нам треба би було вводити також двоцифрові числа. Але зараз не будемо ускладнювати розроблену функцію, а будемо давати питання на ділення чисел. Тоді результат буде однією цифрою. Програма матиме вигляд.
Програма ТаблицяДілення;
Змінні
множ1,множ2,добуток,відповідь,оцінка,питання:цілі;
 Тут записуємо текст опису функції.
Початок
множ1:=random(7)+2;
множ2:=random(7)+2;
добуток:=множ1*множ2;
Позиція(10,10);
Вивести(добуток:2,':',множ1:1,'=?');
відповідь:=результат;
Якщо відповідь<>множ2 то оцінка:=оцінка-1;
Позиція(200,10);
Вивести('оцінка ',оцінка div 2:2)
кінець
кінець.

Завдання.
  • Досі відлагодження програми полягало у виправленні операторів. В цьому випадку треба підібрати дані для програми, щоб швидкість її роботи була розрахована на середнього школяра. Підберіть оптимальний час затримки.
  • Організуйте такий сценарій навчання, щоб час виділявся зразу на всі 10 запитань. Тоді економія часу на легких питаннях дозволяє довше подумати над важкими.
  • Зробіть так, щоб програма задавала тільки важкі питання. Наприклад, якщо перший множник менший за 4, то другий вибирається з діапазону 6..9.
  • Нехай протягом опитування на екрані "падає" кулька (кружечок, який відображається щораз нижче). Правильна відповідь "піднімає" круг, неправильна ігнорується. Швидкість падіння повільно збільшується. Хто краще знає табличку множення і швидко вводить відповідь, той найдовше підтримуватиме кульку в польоті. Напишіть таку програму.
  • ** Модифікуйте програму, щоб забезпечити можливість введення двоцифрової відповіді. Реалізуйте табличку множення з контролем часу.
  • Напишіть сценарії таких програм для інших шкільних предметів.


"Розумний" пульт керування роботом.

Програма створена з метою забезпечення керування роботом таким чином, як це відбувається в ігрових програмах.
program CleverPult;
var
i,j,Kod,Dir:integer;
begin
repeat
event(i,Kod,j);
if (Kod>36) and (Kod<41) then
begin
Dir:=(44-Kod-Direction) mod 4;
case Dir of
0 : if FreeForw then Forward;
1 : Left;
2 : if FreeBack then Backward;
3 : Right;
end
end
else
case Kod of
84 : if Empty and
((InFront=1) or (InFront=2))
then take;
80 : if not Empty and FreeForw
then put;
83 : select;
67 : clear;
end;
coordinates(i,j);
writeln(i,j,direction);
until Kod=27
end.


Програма-годинник.

Завдання цього уроку - розробити програму електронного годинника. На перший погляд все виглядає дуже просто. Для опитування внутрішнього годинника, який є в кожному комп'ютері використовують процедуру Час(i,j,k), яка надає змінним i,j та k значення години, хвилини та секунди на момент звертання до неї. Досить поставити таке опитування в циклі, щоразу виводити значення часу і годинник готовий. Умовою завершення циклу вважатимемо будь-яку подію (натискання клавіші).
Програма годинник;
Змінні
i,j,k : цілі;
Початок
Поки не ЄПодія виконати
Початок
Час(i,j,k);
ВивестиР(i,j,k);
кінець;
кінець.
Якщо Ви запустите на виконання таку програму, то побачите, що всі її недоліки. По-перше, кожне нове значення часу виводиться на новому місці. По-друге, протягом однієї секунди програма декілька разів виводить одне й те саме значення. Так і повинно бути, бо протягом секунди цикл може виконуватись десятки разів.
Щоб позбутися цього, будемо виводити значення часу тільки тоді, коли покази годинника змінилися. Для цього введемо нову змінну сек_поп, значенням якої буде число секунд, яке вже виведене. Вивід здійснюватимемо лише тоді, коли отриманий час відрізняється від вже виведеного. А перед оператором виводу часу поставимо встановлення позиції виводу, щоб нове значення часу виводилося на тому самому місці, затираючи старі покази.
Для красоти виведемо собі ще й дату. Процедура отримання дати теж вимагає трьох змінних. Але звертання до неї відбувається лише раз, тому ми можемо скористатися змінними для часу, хоч їхніми значеннями будуть рік, місяць та день календарної дати. Виведемо інформацію в зручнішій формі і програма може вважатися найпростішим цифровим електронним годинником.
Програма годинник;
Змінні
год,хв,сек,сек_поп:цілі;
Початок
Дата(год,хв,сек);
Вивести(год,хв,сек);
сек_поп:=0;
Поки не ЄПодія виконати
Початок
Час(год,хв,сек);
Якщо сек<>сек_поп то
Початок
Позиція(0,40);
Вивести(год:2,'год ',хв:2,'хв ',сек:2,'сек');
сек_поп:=сек
кінець
кінець;
кінець.
 Недоліком цієї програми є те, що вона не поміняє виведену дату опівночі, але надіємось, що в такий час нормальні люди програмуванням не займаються.
Тепер будемо наводити красоту. А красота, як відомо, вимагає жертв. Основна біда - треба згадувати математику. Але давайте по порядку. Опишемо змінні.
Програма годинник;
Змінні
год,хв,сек,год_поп,хв_поп,сек_поп:цілі;
Перш за все, красивий годинник має бути зі стрілками. А стрілка - це лінія, яка починається в центрі циферблату (наприклад, в точці 160,230), має довжину довж, колір кол і направлена під кутом кут, який відраховується від вертикальної лінії за годинниковою стрілкою і задається в градусах. Вся проблема полягає у визначенні координат кінця стрілки. Розглянемо малюнок. Товстою лінією показана стрілка. Якщо Ви вже згадали тригонометрію, то легко виведете формули для координат кінця стрілки. Зверніть увагу, що від вертикальної координати центра треба віднімати катет трикутника, бо вісь Y на екрані напрвлена вниз. Передбачимо можливість малювання стрілки жовтим (0), червоним (1) та синім кольром. Зрозуміло, що кут нахилу стрілки треба спочатку перевести з градусів в радіани, а значення обчислених координат округлити перед присвоєнням цілим змінним. Процедура малювання стрілки виглядатиме так.
Процедура стрілка( кут, довж, шир, кол : цілі);
Змінні
x,y : цілі;
рад : дійсні;
Початок
рад:=кут*pi/180;
y:=round(230-довж*cos(рад));
x:=round(160+довж*sin(рад));
Випадок кол із
0: Олівець(шир,255,255,0);
1: Олівець(шир,255,0,0);
2,3: Олівець(шир,0,0,200);
кінець;
Лінія(160,230,x,y);
кінець;
Циферблат можна вимальовувати і вдосконалювати без кінця, але це Ви можете робити самостійно. Зараз намалюємо голубий круг радіусом 150 і з центром в точці 160,230. Щоб позначити години, проведемо стрілки синього кольру через кожні 30 градусів. Потім зверху намалюємо жовтий круг трохи меншого радіуса з центром в цій же точці. Циферблат готовий. А процедуру для його побудови пишемо вже.
Процедура циферблат;
Змінні
і : цілі;
Початок
Олівець(2,0,0,200);
Пензлик(1,0,255,255);
Еліпс(10,80,310,380);
Для і:=1 до 12 виконати
стрілка(і*30,150,5,2);
Олівець(2,0,0,200);
Пензлик(1,255,255,0);
Еліпс(14,84,306,376)
кінець;
Циферблат є, стрілки малювати вміємо. Лишилося зробити так, щоб годинник був не просто малюнком, а ще й показував час. Спочатку виведемо красиво дату і намалюємо циферблат.
Початок
КолірТексту(0,0,255);
Шрифт(20,0,400);
Дата(год,хв,сек);
Вивести(год:2,':',хв:2,':',сек:2);
циферблат;
Тепер згадайте, як ми запам'ятовували виведений час в попередній програмі. Зараз будемо запам'ятовувати не тільки секунди, а хвилини та години. Ці значення означатимуть положення, в яких вже намальовані стрілки. Спочатку вважаємо, що попередній час був 0:0:0.
год_поп:=0;
хв_поп:=0;
сек_поп:=0;
Далі записуємо цикл опитування системного годинника, як і в попередній програмі.
Поки не ЄПодія виконати
Початок
Час(год,хв,сек);
Якщо сек<>сек_поп то
Початок
Позиція(0,40);
Вивести(год:2,'год ',хв:2,'хв ',сек:2,'сек');
А тут треба добре поміркувати. При кожному (крім першого) виконанні циклу стрілки вже будуть намальовані. Тому перед тим, як малювати їх в новому положенні, треба витерти намальовані стрілки. А щоб витерти стрілки, просто намалюємо їх ще раз, але кольром циферблату (жовтим). Того, що перший раз малюватимемо жовті стрілки на такому самому фоні, ніхто не помітить. Отже, витираємо стрілки в попередньому положенні. Мабуть не варто нагадувати, що хвилина і секунда - це 6 градусів, а година - 30. Зверніть увагу, що для годин визначається остача від ділення на 12, бо системний годинник дає покази від 0 до 23, за який годинна стрілка повинна зробити два оберти.
стрілка(сек_поп*6,145,1,0);
стрілка(хв_поп*6,120,3,0);
стрілка((год_поп mod 12)*30,80,5,0);
Тепер малюємо стрілки в новому положенні.
стрілка(сек*6,145,1,1);
стрілка(хв*6,120,3,2);
стрілка((год mod 12)*30,80,5,3);
Не забуваємо запам'ятати положення намальованих стрілок.
год_поп:=год;
хв_поп:=хв;
сек_поп:=сек
кінець
кінець;
кінець.
 Програма готова. Запускаємо, радіємо, потім виконуємо такі завдання.
Завдання.
  • Щось наш годинник дуже великий. Попробуйте зменшити його в два рази.
  • Виправте програму так, щоб хвилинна і годинна стрілки рухалися з інтервалом один градус.


Проектуємо калькулятор.

Працюючи на комп'ютері, ми настільки звикли до різноманітних кнопок і кнопочок на екрані монітора, що використовуємо їх так само легко, як кнопки справжньої клавіатури. При цьому не завжди задумуємось, що вся картина на екрані - це результат роботи програмного забезпечення. А якщо й згадуємо про це, то здається, що все це надзвичайно складно.
Однак насправді зображувати та використовувати кнопки на екрані монітора просто і легко. Щоб переконатись в цьому розгляньте уважно малюнок. Якщо верхню і праву сторони прямокутника, намальованого на однотонному фоні, виділити світлішим кольором, а нижню і ліву - темнішим, то створюється враження кнопки, яка виступає над поверхнею планки. Поміняємо кольори місцями - кнопка виявиться втопленою. При цьому можна перемальовувати лише границі прямокутника, а його заповнення залишати незмінним. Очевидно також, що так легко відображати можна лише прямокутні кнопки.

Розробимо програму, яка реалізує простий калькулятор для роботи з цілими числами та демострує використання програмно організованих (віртуальних) кнопок.
Щоб починати роботу, програміст має чітко уявляти собі вигляд екрану під час роботи програми. Нехай майбутній калькулятор виглядатиме приблизно так, як показано на малюнку. Будемо малювати його відтінками зеленого кольору, тобто червону і синю складову прирівнюємо до нуля.
Перш за все сформуємо масив чисел, які задають координати кожної кнопки на калькуляторі. При показаному на малюнку розташуванні кнопок, інформацію про них можна задати більш компактно, але тоді сильно ускладнюється програма. Тому для кожного прямокутника-кнопки задаємо чотири цілі числа, які вказують координати діаметрально протилежних вершин прямокутника. Щоб файл даних був зрозумілішим для читання, першим символом в кожному рядку напишемо той символ, який повинен бути вказаний на кнопці. Крім того, в кінці кожного рядка даних для зручності поставимо номер кнопки.
Всю інформацію запишемо у файлі кнопки.dat. Наведемо можливий вигляд такого файлу

 сим-  координати  номер
 вол     кнопки    кнопки

  0  50 190  70 210 0
  1  50 160  70 180 1
  2  80 160 100 180 2
  3 110 160 130 180 3
  4  50 130  70 150 4
  5  80 130 100 150 5
  6 110 130 130 150 6
  7  50 100  70 120 7
  8  80 100 100 120 8
  9 110 100 130 120 9
  + 140 100 160 120 10
  - 140 130 160 150 11
  * 140 160 160 180 12
  C  80 190 100 210 13
  = 110 190 130 210 14
  / 140 190 160 210 15
Після такої підготовчої роботи можемо починати розробку самої порграми. Перш за все опишемо необхідні змінні. Програма калькулятор;
Константи
N=15;
світлий = 255;
темний = 128;
Змінні
коорд : масив [0..N,1..4] із цілі;
Дані : текст;
i,j: цілі;
число,попереднє,операція:цілі;
напис : символи;
Зверніть увагу, що для написів ми не формуємо масив символів. Кожен символ для позначення кнопки зчитуємо з файлу, виводимо і надалі він не потрібен, тому змінну напис можемо використати для всіх кнопок.
Опис процедур почнемо з процедури відображення кнопки. Формальними параметрами є три цілі змінні, які задають номер кнопки та яскравість верхньої і нижньої половини. Якщо при звертанні верх задати світлий, а низ темний, то кнопка відобразиться відпущеною. Помінявши кольори місцями отримаємо натиснуту кнопку.
Процедура Відобразити( N:цілі; натиснута:логічні);
Змінні верх,низ: цілі;
Початок
Якщо натиснута то
Початок верх:=темний; низ:=світлий кінець
інакше
Початок верх:=світлий; низ:=темний кінець;
Позиція(коорд[N,1],коорд[N,2]);
Олівець(1,0,верх,0);
ЛініяДо(коорд[N,3],коорд[N,2]);
ЛініяДо(коорд[N,3],коорд[N,4]);
Олівець(1,0,низ,0);
ЛініяДо(коорд[N,1],коорд[N,4]);
ЛініяДо(коорд[N,1],коорд[N,2]);
кінець;

Таким чином, малювати кнопки ми вже вміємо. Наступна проблема полягає в тому, щоб якось забезпечити процес вводу інформації від користувача до нашого калькулятора. Це можна здійснити двома шляхами: з клавіатури і від мишки. Виберемо керування мишкою. Для цього напишемо функцію, яка очікує натискання клавіші мишки і повертає номер кнопки, яку натиснув користувач. Очевидно, що така функція повинна приймати ціле значення. Найскладнішим елементом цієї функції є перевірка належності точки ( i , j ), в якій була натиснута клавіша мишки, до області, зайнятої кнопкою з номером k. Це проілюстровано на малюнку. Функція виконує аналіз подій в циклі, поки не буде натиснута клавіша мишки на кнопці калькулятора. Номер цієї кнопки функція повертає як результат.
Функція Опитати : цілі;
Змінні
k,x,y: цілі;
Початок
Опитати := -1;
Подія(k,x,y);
Якщо k=2 то
Для k:=0 до N виконати
Якщо (x>коорд[k,1]) та (y>коорд[k,2])
та (x<коорд[k,3]) та (y<коорд[k,4]) то
Початок
Відобразити(k,так);
Затримка(10);
Опитати := k;
Відобразити(k,ні);
кінець
кінець;
Найпростішою є процедура опрацювання цифрової кнопки. Треба просто число збільшити в 10 разів, додати введену цифру і відобразити результат на індикаторі.
Процедура ДодатиЦифру(k:цілі);
Початок
число:=число*10+k;
Позиція(55,72);
Вивести(число:11);
кінець;

Трохи складніше з кнопками операцій. Справжній калькулятор працює таким чином. Вводиться перше число, запам'ятовується операція потім вводиться наступне число. Результат операції виводять при натисканні кнопки "=" або наступної операції. Напишемо процедуру для виконання операції.
Процедура ВиконатиОперацію;
Початок
Якщо операція>0 то
Початок
Випадок операція із
10: число:=попереднє+число;
11: число:=попереднє-число;
12: число:=попереднє*число;
15: число:=round(попереднє/число);
кінець;
операція:=0;
Позиція(55,72);
Вивести(число:11)
кінець
кінець;

Вся підготовча робота зроблена. Пишемо головну програму.
Початок
Пензлик(1,0,200,0);
Прямокутник(40,60,170,220);
Приєднати( Дані, 'кнопки.dat' );
Встановити( Дані );
Для i:=0 до N виконати
Початок
ВвестиР( Дані, напис,
коорд[i,1],коорд[i,2],
коорд[i,3],коорд[i,4]);
Позиція(коорд[i,1]+4,коорд[i,2]+2);
Вивести(напис);
Відобразити(i,ні);
кінець;
Закрити( Дані );
Пензлик(1,0,255,0);
Прямокутник(50,70,160,90);
число:=0;
попереднє:=0;
операція:=0;
ДодатиЦифру(0);
Поки так виконати
Початок
j:=Опитати;
Випадок j із
0,1,2,3,4,5,6,7,8,9:
ДодатиЦифру(j);
10,11,12,15:
Початок
ВиконатиОперацію;
операція:=j;
попереднє:=число;
число:=0
кінець;
13:
Початок
число:=0;
попереднє:=0;
операція:=0;
ДодатиЦифру(0)
кінець;
14:
ВиконатиОперацію;
кінець
кінець
кінець.

Завдання.
  • Якщо для числа вводити дуже багато цифр, то наш калькулятор не витримує цього. Введіть в програму відповідну перевірку.
  • Зробіть так, щоб у випадку ділення на нуль калькулятор повідомляв про помилку.
  • ** Переробіть калькулятор для роботи з дійсними числами.
  • ** Додайте кнопки перерахунку валют.
  • ** Додайте кнопки потрібних Вам функцій.


Електронний підручник.

Основи роботи ігрових програм.

Ігрові програми - це кара для вчителів інформатики та їхніх учнів. Вчителі всіма доступними засобами намагаються заборонити гратися на уроках і дивуються, як без будь-яких пояснень учні освоюють зовсім не просту систему команд і схему чергової "стрілялки" чи "бродилки". А учням в порівнянні з тими "стрілялками" уроки інформатики видаються такими нудними, що нема слів. Давайте поєднаємо приємне з корисним і навчимося програмувати такі ігри.
Типовий сценарій гри можна сформулювати просто: стріляй у все, що ворушиться. Звичайно, у нас не вистачить часу, щоб малювати всіляких монстрів та зброю. Ми реалізуємо лише стрільбу по рухомій мішені і будемо надіятись, що нестачу художнього оформлення значною мірою компенсує задоволення від того, що програма зроблена самостійно.
Під час роботи ігрової програми на екрані монітора мають бути хоча б два об'єкти: рухома мішень, переміщенням якої керує машина, та приціл, переміщенням якого керує гравець. В момент співпадання їх координат на екрані, гравець має натиснути певну клавішу, щоб здійснити "постріл". Встиг - маєш одне очко, не встиг - починай спочатку.
На попередніх уроках ми вивчали, що подія - це натискання клавіші на клавіатурі або натискання кнопки мишки, коли вказівник мишки перебуває в межах вікна результатів. Повідомлення про подію запам'ятовується. Якщо логічна функція "ЄПодія" повертає істинне значення, то є повідомлення про подію, в протилежному випадку подія ще не відбулася. Отримати інформацію про подію ми можемо за допомогою звертання до процедури Подія(дж,х,у), формальними параметрами якої є три цілі змінні. Змінна дж (джерело) отримує значення 1, якщо натиснута клавіша на клавіатурі. В цьому випадку х - код натисненої клавіші. Коли натиснена кнопка мишки, то дж=2, а х,у - координати вказівника мишки в момент натискання.
Реалізуємо спочатку мішень. Нехай це буде червоний кружечок, який рівномірно рухається всередині зеленого прямокутника, як куля без тертя на більярдному столі. Позначимо через Xm,Ym координати мішені, через dX,dY зміну цих координат за один крок. Щоб створити ілюзію рухомої мішені, треба в циклі перемальовувати мішень щоразу на новому місці. Умовою завершення циклу вважаємо настання якоїсь події. Для того, щоб мішень не "вилетіла" за межі своєї клітки, а відбивалася від її країв, будемо міняти знак dX на протилежний, якщо мішень наблизилась до бічних стінок, та знак dY, якщо мішень наблизилась до верхньої або нижньої стінки. Приймемо, що розмір клітки 250х250 пікселів, і напишемо програму.
  Програма РухомаМішень;
  Змінні Xm,Ym,dX,dY:цілі;
      i,j,k:цілі;
  Процедура МішеньЛетить;
  Початок
    { витираємо (зеленим кольором) мішень }
    Колір(0,255,0);
    КолірПензля(0,255,0);
    Еліпс(Xm-5,Ym-5,Xm+5,Ym+5);
    { якщо за крок мішень вийде за межі клітки,
       то міняємо напрям руху }
    Якщо (Ym<10) або (Ym>240) то dY:=-dY;
    Якщо (Xm<10) або (Xm>240) то dX:=-dX;
    { знаходимо нове положення мішені }
    Xm:=Xm+dX;
    Ym:=Ym+dY;
    { малюємо (червоним кольором) мішень }
    Колір(255,0,0);
    КолірПензля(255,0,0);
    Еліпс(Xm-5,Ym-5,Xm+5,Ym+5);
    { робимо паузу, щоб побачити мішень }
    Затримка(5);
  кінець;
  Початок
    Колір(0,255,0);
    КолірПензля(0,255,0);
    Прямокутник(0,0,250,250);
    Xm:=20; Ym:=20;
    dX:=1;  dY:=2;
    Повторювати МішеньЛетить
    покиНе ЄПодія;
  кінець.
Тепер уже без таких детальних пояснень пишемо програму керування прицілом. Зображуємо приціл у вигляді чорного хрестика, координати якого позначимо через Xp,Yp. Для спрощення ми не перевіряємо, чи приціл не вийшов за межі прямокутника.
  Програма КеруємоПрицілом;
  Змінні Xp,Yp:цілі;
      i,j,k:цілі;
  Процедура Приціл(X,Y:цілі);
  { X,Y - координати, в які потрібно поставити приціл }
  Початок
    { витираємо (зеленим кольором) приціл }
    Колір(0,255,0);
    Лінія(Xp,Yp-5,Xp,Yp+5);
    Лінія(Xp-5,Yp,Xp+5,Yp);
    { запам'ятовуємо нові координати }
    Xp:=X; Yp:=Y;
    { малюємо (чорним кольором) приціл }
    Колір(0,0,0);
    Лінія(Xp,Yp-5,Xp,Yp+5);
    Лінія(Xp-5,Yp,Xp+5,Yp);
  кінець;
  Початок
    Колір(0,255,0);
    КолірПензля(0,255,0);
    Прямокутник(0,0,250,250);
    Xp:=100;Yp:=100;
    Приціл(Xp,Yp);
    Повторювати
      Подія(k,i,j);
      Якщо k=1 то
        Початок
          Випадок i із
            37 : Приціл(Xp-5,Yp);  { стрілка вліво }
            38 : Приціл(Xp,Yp-5);  { стрілка вгору }
            39 : Приціл(Xp+5,Yp);  { стрілка вправо }
            40 : Приціл(Xp,Yp+5);  { стрілка вниз }
          кінець
        кінець
    покиНе (k=1) та (i=27) { клавіша Esc }
  кінець.
Таким чином, обидва об'єкти реалізовані, але окремо. Тепер будемо з'єднувати їх в одній програмі. Зрозуміло, що в розділі описів треба перелічити всі змінні та помістити обидві процедури.
Виникає ще одна деталь. Приціл повинен весь час знаходитись на передньому плані. Якщо мішень пролітає через точку, в якій знаходиться приціл, вона не повинна затирати його. Щоб зробити так, поставимо перед оператором Затримка в процедурі МішеньЛетить перевірку. У випадку, коли мішень витерла частину прицілу, перемалюємо його. Відповідний оператор матиме вигляд:
    Якщо (abs(Xm-Xp)<10) та
       (abs(Ym-Yp)<10) то
         Приціл(Xp,Yp);
Поставимо першим оператором циклу керування прицілом оператор повторення польоту мішені.
    Повторювати МішеньЛетить
    покиНе ЄПодія;
Нехай "постріл" здійснюється клавішею пробілу, код якої 32. Додамо в оператор вибору опрацювання натискання клавіші пробілу. Ми не повинні перевіряти, чи в момент пострілу мішень та приціл мали однакові координати, бо тоді попасти в мішень буде практично неможливо. Досить щоб відстань між ними була менша за 10 пікселів.
          32 :  { натиснений пробіл }
              Якщо(abs(Xm-Xp)<10) та (abs(Ym-Yp)<10) то
                 Початок { попадання }
                   { великим жовтим кругом показуємо вибух }
                   КолірПензля(255,255,0);Колір(255,255,0);
                   Еліпс(Xm-30,Ym-30,Xm+30,Ym+30);
                   { робимо паузу, щоб побачити вибух }
                   Затримка(50);
                   { витираємо жовтий круг }
                   КолірПензля(0,255,0);Колір(0,255,0);
                   Еліпс(Xm-30,Ym-30,Xm+30,Ym+30);
                   { випадкомим чином вибираємо положення та
                     швидкість руху нової мішені }
                   Xm:=random(200)+20; Ym:=random(200)+20;
                   dX:=random(4); dY:=random(4);
                   { відновлюємо приціл, який затерли вибухом }
                   Приціл(Xp,Yp);
                кінець;
Програма готова. Можете трошки постріляти.
Оскільки урок ігровий, то завдань не буде. Але сподіваюся, що Ви самостійно підберете такі значення затримки і швидкостей, щоб було зручно грати. Можете попробувати вести підрахунок числа влучань і промахів. В залежності від кількості пострілів можна збільшувати швидкість польоту мішені. Це в більшості ігрових програм означає рівень.
Якщо програма видається Вам занадто складною, можете викинути з неї приціл і керування ним, а "роздушувати" мішень просто вказівником мишки.
Якщо все просто і зрозуміло, можете ускладнити траєкторію польоту мішені. Для цього досить міняти крок переміщення мішені кожного разу на невелику (випадкову чи вибрану іншим способом) величину.
Експериментуйте!


Побудова графіка.

program graph;
var
Data : array [1..1000] of real;
NumbData : integer;
procedure MyGraph;
var
xPos,yPos,i:integer;
DataMax,DataMin : real;
begin
DataMin:=Data[1];
DataMax:=Data[1];
for i:=2 to NumbData do
begin
if Data[i]>DataMax then
DataMax:=Data[i];
if Data[i]<DataMin then
DataMin:=Data[i];
end;
if DataMin>0.0 then
yPos:=300
else
if DataMax<0.0 then
yPos:=0
else
yPos:=round(300-(0.0-DataMin)/(DataMax-DataMin)*300);
Pen(1,0,0,200);
Brush(1,0,250,250);
Rectangle(0,0,405,305);
Brush(1,200,0,200);
yPos:=round(300-(Data[1]-DataMin)/(DataMax-DataMin)*300);
Ellipse(-4,yPos-4,4,yPos+4);
MoveTo(0,yPos);
for i:=2 to NumbData do
begin
xPos:=round(i*400/NumbData);
yPos:=round(300-(Data[i]-DataMin)/(DataMax-DataMin)*300);
LineTo(xPos,yPos);
Ellipse(xPos-4,yPos-4,xPos+4,yPos+4);
end;
end;
begin
NumbData:=0;
for NumbData:=1 to 100 do
begin
Data[NumbData]:=sin(NumbData*0.2);
end;
MyGraph;
end.


Електронний підручник.

Пошук виходу з лабіринту.

Не переказуючи казок про Мінотавра і його лабіринти, зразу сформулюємо умову завдання для робота. Треба відшукати вихід в системі коридорів, тримаючись лівої стіни.
Але так можна сказати людині. В системі команд робота немає нічого подібного до команди "тримайся стіни". Тому ми повинні сформулювати цю задачу, користуючись засобами мови Паскаль та допустимими командами робота.
Отже робот повинен йти, поки не знайде вихід. Виявити вихід робот може лише за допомогою функції Локатор, яка в цьому випадку повертає значення 2. Таким чином, робот повинен повторювати якісь дії в циклі, поки попереду нього не виявиться вихід. Запишемо це на Паскалі.
Програма Find;
Початок
Поки не (Локатор=2) виконати
При кожному [image] повторенні циклу, ми не знаємо, в якій обстановці опиниться робот. Але оскільки йому треба йти вздовж лівої стіни, то перш за все опитаємо, чи вільний шлях зліва.
Якщо [image] зліва вільно, то треба повернутись ліворуч і зробити крок вперед.
Якщо ВільноЗліва то
Початок Наліво; Вперед кінець
Тут ми уже [image] знаємо, що наліво дороги немає. Перевіряємо, чи вільна дорога попереду.
Якщо [image] вільно попереду, то робимо крок вперед.
інакше Якщо ВільноПопереду то
Вперед
Якщо ж [image] нема вільного шляху ні зліва, ні попереду, то повертаємо праворуч.

інакше Направо
кінець.
 Програма готова. Переконайтеся, що керуючись такою програмою, робот знаходить вихід з довільного лабіринту, в якому немає замкнених шляхів.
Завдання.
  • Змініть програму, щоб робот рухався вздовж правої стіни.
  • Наведіть приклади лабіринтів, з яких робот не знайде виходу.
  • Як буде поводитись робот, коли навколо нього не буде стін?


Моделювання польоту тіла.

Давайте напишемо програму, яка моделює рух тіла, кинутого під кутом до горизонту. І не просто побудуємо траєкторію руху, а зробимо так, щоб на екрані отримати дійсно рухоме тіло.
Більшість з вас, мабуть, починає зразу гарячково згадувати відповідні формули з фізики. Не лякайтеся, якщо Ви не знаєте цих формул. На цьому уроці ми відкриємо для себе чудову властивість комп'ютерного моделювання. Виявляється, що за допомогою програмних методів можна отримувати розв'язки задач, які взагалі не можна записати у вигляді формул. Але про це ми поговоримо, коли програма буде готова.
Це не означає, що можна взагалі нічого не знати. Зрозуміло, що для моделювання польоту тіла треба знаходити в кожний момент часу висоту H, дальнісь L, знати горизонтальну Vx та вертикальну Vy складові швидкості. Зверніть увагу, що вертикальна складова швидкості направлена вверх. Прискорення вільного падіння позначимо g.
Поділимо час польоту на такі маленькі проміжки dT, протягом яких швидкість міняється на таку малу величину, що рух можна вважати рівномірним. Протягом одного такого проміжку тіло пролетить в горизонтальному напрямі відстань Vx*dT, а у вертикальному - Vy*dT. Горизонтальна складова швидкості не змінюється, а вертикальна за час dT зменшиться на g*dT.
На цьому з фізикою можна закінчити і перейти до програмування. Всі змінні і константи в нашій задачі є дійсними числами. Спочатку напишемо головну програму, а потім по черзі будемо розробляти необхідні для неї процедури. Програма виявляється надзвичайно простою. Потрібно кинути тіло і спостерігати, як воно летить, поки тіло не упало. Так і запишемо.
Програма ПолітТіла;
Константи
g=9.82;
крок=0.1;
Змінні
Час,Висота,Дальність,Vx,Vy:дійсні;
номер:цілі;
................
Початок
Прямокутник(0,0,600,200);
Для номер:=1 до 10 виконати
Початок
Кинути;
Затримка(100);
Повторювати
Летить
покиНе упало;
Затримка(500)
кінець
кінець.
Крапочками показане місце, де розміщуємо опис процедур та функцій, до написання яких ми і перейдемо. Що означає "кинути"? Треба задати початкові координати і швидкість. Так і пишемо.
Процедура Кинути;
Початок
Дальність:=0;
Висота:=40;
Час:=0;
Vx:=random(40.0)+20.0;
Vy:=random(50.0);
Намалювати;
кінець;
Так само просто виглядає функція "упало", яка мусить повертати значення логічного типу. Тіло упало, якщо висота польоту рівна нулю або менша.
Функція упало:логічні;
Початок
упало:=Висота<=0;
кінець;
Але не все так просто. Треба все-таки малювати тіло та ще й зробити його рухомим. Ви маєте зрозуміти, що на екрані монітора, як і в кіно, нічого не рухається. Це все ілюзія. Щоб створити враження руху, треба швидко відтворювати на екрані нові зображення. В нашому випадку це означає, що потрібно витерти намальоване тіло і намалювати його на новому місці. Витерти - означає замалювати тіло кольором фону (білим).
Всі координати на екрані задають цілими числами, причому вісь Y направлена зверху вниз. Тому в процедурі описуємо змінні x та y, які означають координати зображення тіла на екрані.
Процедура Стерти;
Змінні
x,y:цілі;
Початок
x:=round(Дальність);
y:=round(200.0-Висота);
Олівець(1,255,255,255);
Пензлик(1,255,255,255);
Прямокутник(x-5,y-5,x+5,y+5)
кінець;
Процедура Індикатор;
Початок
Позиція(0,210);
ВивестиР('Час ',Час:8:2);
ВивестиР('Висота ',Висота:8:2);
ВивестиР('Дальність',Дальність:8:2);
кінець;
Процедура Намалювати;
Змінні
x,y:цілі;
Початок
x:=round(Дальність);
y:=round(200.0-Висота);
Олівець(1,255,0,0);
Пензлик(1,0,255,0);
Еліпс(x-5,y-5,x+5,y+5);
Індикатор;
Затримка(1);
кінець;
Не так уже й складно виходить. Давайте подумаємо, що повинна робити процедура "Летить", звертання до якої здійснюється в циклі головної програми. Мабуть, при кожному звертанні ця процедура має витерти тіло на старому місці, порахувати нові координати і знову намалювати тіло. Кожне звертання до процедури "Летить" відповідає моделювання руху протягом одного проміжку часу dT. Але на комп'ютері моделювання всього процесу триватиме соті долі секунди, і ніхто нічого не встигне побачити. Щоб уникнути цього, робимо штучну паузу.
Процедура Летить;
Початок
Стерти;
Висота:=Висота+Vy*крок;
Vy:=Vy-g*крок;
Дальність:=Дальність+Vx*крок;
Час:=Час+крок;
Намалювати;
кінець;
Виконуючи програму, Ви побачите, що тіло рухається по параболі, хоч ми цього і не виводили. Перед тим, як почати обговорення цієї програми, виконайте кілька простих завдань.
  • Поставте в головній програмі вивід осей координат.
  • Змініть процедуру Кинути так, щоб початкова висота, швидкість та кут кидання вводились з клавіатури.
  • Після завершення польоту виведіть значення дальності, максимальної висоти та часу польоту.
  • Виберіть будь-яку задачу цього розділу з підручника фізики і підберіть таке значення dT, щоб результати отримувались з заданою точністю.
Все, що ми робили досі, можна було зробити набагато простіше. Для цього досить знайти в підручнику відповідні формули для траєкторії руху тіла і побудувати графік. При цьому отримані значення будуть точними при будь-якому значенні dT. Але це тільки при умові, що опором повітря можна знехтувати. А для практичних задач цього робити не можна майже ніколи. Справді, чи має сенс розрахунок часу падіння парашутиста, якщо опором повітря знехтувати? Хоч впевнено почуває себе на уроках фізики, може попробувати рішити таку задачу. Знайти час падіння парашутиста масою 80 кг з висоти 1 км, якщо сила опору повітря залежить від швидкості падіння за формулою F=К*V*V, де коефіцієнт К в системі СІ має значення 100.
Не виходить? А ми за допомогою програми розв'язуємо такі задачі дуже просто. На малюнку показані вектори швидкостей та сил для польоту під довільним кутом. Сила опору завжди направлена протилежно до швидкості руху. Остаточно отримуємо:
Fx=K*Vx/V;
Fy=K*Vy/V;
 Швидкість знаходять як корінь квадратний із суми квадратів вертикальної і горизонтальної складових.
Для такої зміни в програмі треба додатково описати змінні К (коефіцієнт), V (швидкість), М (маса). Тепер поміняємо перерахунок координат в процедурі "Летить".
  Процедура Летить;
  Початок
    Стерти;
    H:=H+Vy*dT;
    L:=L+Vx*dT;
    V:=sqrt(sqr(Vx)+sqr(Vy));
    Vx:=Vx-K*Vx/V/M*dT;
    Vy:=Vy-(g+K*Vy/V/M)*dT;
    Намалювати;
    Затримка(1);
  кінець;
Не забудьте, що треба змінним К та М надати значення.
Підведемо підсумок. За допомогою поділу часу на маленькі інтервали ми можемо отримати розв'язок задач, які інакшими методами отримати неможливо. Зменшуючи значення інтервалу, можна добитися довільної наперед заданої точності отриманих результатів.
Завдання.
  • Розв'яжіть за допомогою програми задачу про парашутиста.
  • Змініть залежність сили опору на таку F=K1*V+K2*V*V. Підберіть значення коефіцієнтів.
  • Побудуйте траєкторії руху з опором повітря і без опору та порівняйте їх.


Програмуємо робота-вантажника.

Про робота-вантажника та систему його команд Ви можете прочитати в довідковій системі. На цьому уроці напишемо просту програму керування роботом. Алгоритм роботи цієї програми такий:
- з клавіатури вводиться команда, яка є однією буквою;
- програма розпізнає введену букву і дає роботу відповідну команду;
- якщо введена команда не означає "кінець роботи", то повертаємось до першого кроку.
Для організації такого циклічного алгоритму в Паскалі використовують оператор повторення, який має вигляд
    Повторювати
        серія операторів
    покиНе умова
У нашому випадку можемо записати цей алгоритм так
    Повторювати
        ввести команду;
        виконати команду
    покиНе команда завершення роботи
В кожному випадку потрібно виконувати одну з багатьох можливих команд. Для цього використовують оператор вибору. Його дія очевидна, тому запишемо цей оператор зразу для нашої задачі.
Випадок com із
'f': Вперед;
'b': Назад;
'l': Наліво;
'r': Направо;
's': Помітити;
'c': Витерти;
't': Взяти;
'p': Покласти;
інакше ВивестиР('невідома команда');
кінець
У випадку, коли введена команда є однією з перелічених букв, то програма посилає роботу відповідну вказівку. Якщо введений символ не співпадає з жодним, то виконується оператор, який записаний після слова інакше і програма виводить рядок "невідома команда".
Позначення команд зрозумілі з тексту оператора. Позначимо команду завершення роботи буквою e і напишемо готову до виконання програму.
Програма PULT;
Змінні com:символи;
Початок
Повторювати
Ввести(com);
Випадок com із
'f': Вперед;
'b': Назад;
'l': Наліво;
'r': Направо;
's': Помітити;
'c': Витерти;
't': Взяти;
'p': Покласти;
інакше ВивестиР('невідома команда');
кінець
покиНе com='e'
кінець.
 Виконаємо програму. Після запуску програма очікує вводу з клавіатури. Введемо букву f і натиснемо Enter для завершення вводу. Робот зробить крок вперед, після чого програма несподівано для нас повідомить невідома команда. Але ж ми ввели лише одну букву. Програма правильно сприйняла її. Звідки ж взялося повідомлення?
Виявляється, що все набагато складніше, ніж ми собі дотепер уявляли. Будь-яка інформація, яку вводять з клавіатури, не передається в програму відразу, а записується в спеціальний буфер. Цей буфер є рядком символів. Коли Ви вводите інформацію, то насправді редагуєте цей рядок. Щоб повідомити про закінчення підготовки інформації в буфері, Ви і натискаєте клавішу Enter. При цьому останнім в рядку записується символ з кодом 13, який означає перехід на новий рядок. Саме про цей символ наша програма і повідомляла. Щоб позбутися цього повідомлення, можна використати замість оператора Ввести оператор ВвестиР, який вводить інформацію з буфера, після чого прибирає з нього всі символи включно з символом переходу на новий рядок. Попробуйте зробити це.
Ми ж будемо далі використовувати оператор Ввести, щоб вияснити ще одну цікаву деталь. Після завершення підготовки інформації в буфері введення, програма читає з нього до тих пір, поки не прочитає останній символ. Тільки після цього вона знову очікує вводу нового рядка в буфер. Таким чином, можемо ввести в буфер набагато більше інформації, ніж потрібно для конкретного оператора вводу. Щоб переконатись в цьому підготуємо показану на малюнку схему і введемо цілий рядок команд.
f f l f f f l f f l f t f

В лівій половині малюнка показано положення робота до початку виконання, в правій - після виконання. Для наглядності команди написані в тих клітинках, де робот їх отримав.
Погодьтеся, що вводити команди такими серіями зручніше, ніж по одній. А якщо Вам заважає повідомлення про невідому команду, то після оператора вводу поставте перевірку. Якщо введений символ є переходом на новий рядок, то ввести наступний символ.
    Якщо команда=chr(13) то
        Ввести(команда);

Завдання.
  • Виконайте всі перевірки, про які йшлося в тексті уроку.
  • Зробіть, щоб програма при вводі кінця рядка повідомляла не невідома команда, а Команди виконані. Вводьте нові!.
  • Будь-яка помилка при вводі серії команд приводить до аварійного завершення програми. Модифікуйте програму так, щоб робот завжди перевіряв можливість виконання команди. Наприклад.
        Якщо ВільноПопереду то Вперед
    інакше Вивести('Не полізу ж я на стіну!);


Електронний підручник.

Програма швидкого сортування масиву.

Програма переписана з демонстраційних прикладів Turbo Pascal.
  { Turbo Sort }
  { Copyright (c) 1985,90 by Borland International, Inc. }
  Program qsort;
  {$R-,S-}
  { This program demonstrates the quicksort algorithm, which      }
  { provides an extremely efficient method of sorting arrays in   }
  { memory. The program generates a list of 1000 random numbers   }
  { between 0 and 29999, and then sorts them using the QUICKSORT  }
  { procedure. Finally, the sorted list is output on the screen.  }
  { Note that stack and range checks are turned off (through the  }
  { compiler directive above) to optimize execution speed.        }
  Const
    max = 100;
  Type
    list = array[1..max] of integer;
  Var
    data: list;
    i: integer;
  { QUICKSORT sorts elements in the array A with indices between  }
  { LO and HI (both inclusive). Note that the QUICKSORT proce-    }
  { dure provides only an "interface" to the program. The actual  }
  { processing takes place in the SORT procedure, which executes  }
  { itself recursively.                                           }
  Procedure quicksort(Var a: list;
    Lo,Hi: integer);
  Procedure sort(l,r: integer);
  Var
    i,j,x,y: integer;
  Begin
    i:=l;
    j:=r;
    x:=a[(l+r) div 2];
    Repeat
      While a[i]<x do
        i:=i+1;
      While x<a[j] do
        j:=j-1;
      If i<=j then
        Begin
          y:=a[i];
          a[i]:=a[j];
          a[j]:=y;
          i:=i+1;
          j:=j-1;
        end;
    until i>j;
  If l<j then
    sort(l,j);
  If i<r then
    sort(i,r);
  end;
  Begin
  {quicksort};
    sort(Lo,Hi);
  end;
  Begin
  {qsort}
    Write('Now generating 100 random numbers...');
    For i:=1 to max do
      data[i]:=random(30000);
    WriteLn;
    WriteLn('Now sorting random numbers...');
    quicksort(data,1,max);
    WriteLn;
    For i:=1 to max do
      WriteLn(data[i]:8);
  end.


Інтерпретатор простих виразів.

До цього часу всі Ваші знання про компілятори обмежувались усвідомленням необхідності існування деякої програми, яка перекладає конструкції алгоритмічної мови високого рівня в машинні коди. Інтерпретатор відрізняється від компілятора тим, що не записує програму в машинних кодах, а зразу виконує її.
Теорія конструювання мов програмування та перекладу програм з однієї мови на іншу, зокрема машинну, є окремою галуззю науки. На цьому уроці ми познайомимось з елементами процесу розпізнавання і виконання програм на простому прикладі. Візьмемо таку задачу.
З клавіатури вводять рядок тексту, який містить цілі числа, розділені знаками арифметичних операцій. Треба порахувати і вивести значення введеного виразу. Для спрощення вважаємо, що рядок не містить пробілів і починається з числа.
Дуже важливо для такого типу задач чітко розуміти процес вводу інформації. Прочитайте розділ "Текстові файли. Ввід з клавіатури." довідкової системи. Аналіз тексту, який потрібно інтерпретувати (в нашому випадку арифметичний вираз, значення якого треба порахувати), будують таким чином, щоб текст вводився символ за символом і зразу аналізувався. Це дозволяє не тримати в оперативній пам'яті всього тексту.
Нехай в буфері вводу знаходиться вираз, який користувач набрав на клавіатурі. Вираз складається з доданків, множників і т.д. Будемо розробляти програму таким чином, щоб кожному з цих понять відповідала процедура чи функція, яка вводить всі символи даного елементу виразу і вираховує значення цього елементу. Опишемо змінну сим, яка є поточним прочитаним символом. Розглянемо процес вводу на прикладі цілого числа. Ми вводимо число цифра за цифрою і завершуємо введення, коли введений символ не є цифрою. Але ми вже ввели його! Вияснити, яким буде наступний символ не прочитавши його неможливо. Тому мусимо сформулювати таке правило. Процедура чи функція, яка аналізує елемент виразу, вводить також наступний символ, який вже не належить до даного елементу. Наслідком цього правила є той факт, що перший символ кожного елементу виразу вводиться до виконання функції, яка аналізує цей елемент. Проілюструємо це на малюнку.

Синім кольром підкреслене число 1458, яке вводиться. Сивол "1" був введений попередньою процедурою і є значенням змінної сим. Функція, яка аналізує число, вводить символи, виділені червоним кольором. Після її завершення змінна сим набуває значення "-".
Тепер вже можемо писати програму. Опишемо необхідні змінні.
Програма вираз;
Змінні
сим :символи;
значення: дійсні;
Відомі Вам з арифметики поняття співмножник, ділене, дільник об'єднаємо збірним поняттям множник і напишемо функцію для його введення і підрахунку. При цьому використаємо той факт, що в таблиці кодування символів цифри розміщені по порядку і мають номери від 48 ("0") до 57 ("9"). Множниками в нашому прикладі є цілі числа.
Функція множник: дійсні;
Змінні
число:дійсні;
Початок
число:=0;
Повторювати
число:=число*10+ord(сим)-48;
Ввести( сим )
покиНе (сим<'0') або (сим>'9');
множник:=число
кінець;
Аналогічно до попереднього випадку зменшуване, від'ємник, доданок об'єднаємо поняттям доданок і напишемо функцію для нього. Функція вводить числа (множники), поки вони сполучені знаками множення та ділення і виконує відповідні операції.
Функція доданок: дійсні;
Змінні число: дійсні;
Початок
число:=множник;
Поки (сим='*') або (сим='/') виконати
Якщо сим='*' то
Початок
Ввести(сим);
число:=число*множник
кінець
інакше
інакше
Початок
Ввести(сим);
число:=число/множник
кінець;
доданок:=число;
кінець;
Тепер залишилось вводити "доданки", поки вони сполучені символами додавання або віднімання. Зробимо це у виконуваній частині головної програми. Згадайте, що перший символ елементу виразу має бути введений перед звертанням до функції аналізу цього елементу. Тому першим стоїть оператор введення символа.
Початок
Ввести(сим);
значення:=доданок;
Поки (сим='+') або (сим='-') виконати
Якщо сим='+' то
Початок
Ввести(сим);
значення:=значення+доданок
кінець
інакше
Початок
Ввести(сим);
значення:=значення-доданок
кінець;
Вивести(значення)
кінець.
 Проаналізуємо ще раз роботу програми в цілому. Головна програма вводить перший символ і звертається до функції доданок. Функція доданок звертається до функції множник, яка повертає перше число. Якщо далі записаний символ множення або ділення, то функція доданок читає наступний символ і знову звертається до обчислення множника. Якщо зустрінеться будь-який символ крім цифри, "*" і "/", то обчислення доданка припиняється і його значення повертається в головну програму. Головна програма аналогічно формує значення виразу за допомогою операцій додавання та віднімання. Легко бачити, що виконання програми завершується, коли зустрінеться символ кінця стрічки, інший непередбачений символ або помилка. Перевірте це!
Завдання.
  • Якщо ввести в умову задачі, що вираз завершується символом "=", то в кінці виконання програми має виконуватись умова сим='='. Якщо ця умова не виконується, то у виразі допущено помилку. Добавте в програму діагностику помилки.
  • Змініть функцію множник так, щоб буква "п" сприймалась програмою, як число 3.141595.
  • Модифікуйте програму так, щоб пробіли пропускалися.
  • Реалізуйте перевірку ділення на нуль.
  • Змініть функцію множник так, щоб у виразі можна було писати дійсні числа, наприклад, 17.345.
  • Запишіть вирахування виразу у вигляді окремої функції вираз, щоб виконувана частина головної програми могла бути записана в такому вигляді:
    Початок
    Ввести(сим);
    Вивести(вираз)
    кінець.
  • Використовуючи результат попереднього завдання, забезпечте можливість використання круглих дужок у виразах. Для цього досить зрозуміти, що множник це ціле число або вираз в дужках, для вирахування якого функція множник має звернутись до функції вираз.


Приклад програми.

 program E1;
var
a,b:real;
begin
write('введіть два числа через пробіл, потім натисніть Enter');
readln(a,b);
writeln('a+b=',a+b,'a*b=',a*b,'a-b=',a-b)
end.
Повернутися до списку


Приклад програми.

 program E2;
var
a,b,x,y,z:real;
begin
write('введіть два числа через пробіл, потім натисніть Enter');
readln(a,b);
x:=a+b;
y:=a*b;
z:=a-b;
writeln('a+b=',x,'a*b=',y,'a-b=',z)
end.
Повернутися до списку


Приклад програми.

 program E3;
var
a,b:integer;
begin
write('введіть два цілих числа');
readln(a,b);
if a mod 2 = 0 then
writeln('a - парне')
else
writeln('a - непарне');
if b mod 2 = 0 then
writeln('b - парне')
else
writeln('b - непарне')
end.
Повернутися до списку


Приклад програми.

 program E4;
var
a,b,c:real;
begin
write('введіть довжини трьох сторін трикутника');
readln(a,b,c);
write('трикутник зі сторонами ',a,b,c);
if (a+b>c) and (b+c>a) and (c+a>b) then
writeln('існує')
else
writeln('не існує')
end.
Повернутися до списку


Приклад програми.

 program E5;
label 1,2;
var
a,b:integer;
begin
write('введіть два натуральних числа');
readln(a,b);
1: if a=b then
goto 2;
if a>b then
a:=a-b
else
b:=b-a;
goto 1;
2: writeln('НСД=',a)
end.
Повернутися до списку


Приклад програми.

 program E6;
label 1,2;
var
a,b:integer;
begin
write('введіть два натуральних числа');
readln(a,b);
while a<>b do
if a>b then
a:=a-b
else
b:=b-a;
writeln('НСД=',a)
end.
Повернутися до списку


Приклад програми.

 program E7;
var
a,b:integer;
begin
write('введіть два натуральних числа');
readln(a,b);
repeat
if a>b then
a:=a-b;
if b>a then
b:=b-a;
until a=b;
writeln('НСД=',a)
end.
Повернутися до списку


Приклад програми.

 program E8;
var
a,p:real;
i,n:integer;
begin
write('введіть a - основу степеня, а=');
readln(a);
write('введіть ціле n - показник степеня, n=');
readln(n);
p:=1;
for i:=1 to n do
p := p * a;
writeln('p=',p)
end.
Повернутися до списку


Приклад програми.

 program E9;
var
p,i,n:integer;
begin
write('введіть ціле n=');
readln(n);
p:=1;
for i:=1 to n do
p := p * i;
writeln(n,'!=',p)
end.
Повернутися до списку


Приклад програми.

 program E10;
var
x,y:real;
begin
x:=0;
writeln('x':10,'sin x':10);
while x<=3.14 do
begin
y:=sin(x);
writeln(x:10,' ',y:7:5);
x:=x+0.1
end
end.
Повернутися до списку


Приклад програми.

 program E11;
var
a,s:real;
i,n:integer;
begin
write('введіть кількість доданків n=');
readln(n);
s:=0;
for i:=1 to n do
begin
write(i,'-е число =');
readln(a);
s:=s+a
end;
writeln('сума s=',s)
end.
Повернутися до списку


Приклад програми.

 program E12;
var
A,eps,x0,x1:real;
begin
write('введіть додатне число А=');
readln(A);
write('введіть точність обчислень');
readln(eps);
x0 := 1;
x1 := 0.5*(x0 + A / x0);
while abs(x1-x0) > eps do
begin
x0 := x1;
x1 := 0.5*(x0 + A / x0);
end;
writeln('корінь квадратний з числа ',A,'=',x1)
end.
Повернутися до списку


Приклад програми.

 program E13;
var
x,a,s,eps:real;
n2:integer;
begin
write('x=');
readln(x);
write('eps=');
readln(eps);
a:=x;
s:=x;
n2:=1;
repeat
a:=-a * sqr(x)/((n2+1)*(n2+2));
s:=s+a;
n2:=n2+2
until abs(a) < eps;
writeln('sin ',x,'=',s)
end.
Повернутися до списку


Приклад програми.

 program E14;
var
a,b,c,eps:real;
begin
a:=0;
b:=1;
eps:=0.0001;
while abs(b-a) > eps do
begin
c:=(a+b)/2;
if(a*a-cos(a)+0.5)*(c*c-cos(c)+0.5)>0 then
a:=c
else
b:=c
end;
writeln('корінь f(x) на відрізку ',a,',',b,'=',(a+b)/2)
end.
Повернутися до списку


Приклад програми.

 program E15;
const
n=7;
var
a : array [1..n] of real;
s: real;
i:integer;
begin
Write('вводьте елементи масиву -');
Write(n,' дійсних чисел через пропуск');
for i:=1 to n do
read(a[i]);
s:=0;
for i:=1 to n do
s:=s+a[i];
writeln;
writeln('сума елементів масиву s=',s)
end.
Повернутися до списку


Приклад програми.

 program E16;
const
n=7;
var
a : array [1..n] of integer;
max,i:integer;
begin
for i:=1 to n do
begin
write('a[',i,']=');
readln(a[i]);
end;
max:=a[1];
for i:=2 to n do
if max<a[i] then
max:=a[i];
writeln('найбільший елемент масиву max=',max)
end.
Повернутися до списку


Приклад програми.

 program E17;
const
n=7;
var
a : array [1..n] of real;
i,j:integer;
c:real;
begin
for i:=1 to n do
begin
write('a[',i,']=');
readln(a[i]);
end;
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i]>a[j] then
begin
c:=a[i];
a[i]:=a[j];
a[j]:=c
end;
writeln('упорядкований за зростанням масив');
for i:=1 to n do
writeln(a[i])
end.
Повернутися до списку


Приклад програми.

 program E18;
label 1,2;
const
n=7;
var
a : array [1..n] of real;
x:real;
i:integer;
begin
write('введіть елементи масиву');
for i:=1 to n do
readln(a[i]);
writeln;
write('введіть число для пошуку в масиві x=');
readln(x);
for i:=1 to n do
if a[i]=x then
goto 1;
write('такого числа в масиві немає');
goto 2;
1:writeln('номер елемента масиву, що дорівнює даному ',i);
2:
end.
Повернутися до списку


Приклад програми.

 program E19;
const
n=3;
var
b : array [1..n, 1..n ] of real;
i,j:integer;
s:real;
begin
writeln('введіть значення елементів таблиці порядково');
writeln('в кінці кожного рядка натискайте Enter');
for i:=1 to n do
begin
for j:=1 to n do
read(b[i,j]);
writeln;
end;
s:=0;
for i:=1 to n do
s:=s+b[i,i];
write('сума елементів діагоналі таблиці S=',s);
end.
Повернутися до списку


Приклад програми.

 program E20;
const
n=3;
var
b : array [1..n, 1..n ] of integer;
i,j:integer;
a: array [1..n] of integer;
begin
writeln('введіть значення елементів таблиці порядково');
writeln('в кінці кожного рядка натискайте Enter');
for i:=1 to n do
begin
for j:=1 to n do
read(b[i,j]);
writeln;
end;
{побудова масиву найбільших значень
елементів рядків таблиці}
for i:=1 to n do
begin
a[i]:=b[i,1];
for j:=2 to n do
if a[i]<b[i,j] then
a[i]:=b[i,j];
end;
writeln('найбільші числа рядків таблиці');
for i:=1 to n do
writeln(a[i])
end.
Повернутися до списку


Приклад програми.

 program E21;
const
n=3;
var
b : array [1..n, 1..n ] of integer;
S,i,j:integer;
a: array [1..n] of integer;
begin
writeln('введіть значення елементів таблиці порядково');
writeln('в кінці кожного рядка натискайте Enter');
for i:=1 to n do
begin
for j:=1 to n do
read(b[i,j]);
writeln;
end;
{побудова масиву сум елементів стовпців таблиці}
for j:=1 to n do
begin
S:=0;
for i:=1 to n do
S:=S+b[i,j];
a[j]:=S;
end;
writeln('суми елементів стовпців таблиці');
for i:=1 to n do
writeln(a[i])
end.
Повернутися до списку


Приклад програми.

 program E22;
const
n=3;
m=4;
var
b : array [1..n, 1..m ] of real;
c : real;
i,j,K,L : integer;
begin
write('введіть номери рядків таблиці, що міняються місцями');
readln(K,L);
{введення таблиці}
for i:=1 to n do
begin
writeln(i,'-й рядок таблиці');
for j:=1 to m do
read(b[i,j]);
writeln
end;
{перестановка рядків}
for j:=1 to m do
begin
c:=b[K,j];
b[K,j]:=b[L,j];
b[L,j]:=c
end;
{друкування результатів}
writeln;
writeln('таблиця з переставленими рядками');
for i:=1 to n do
begin
for j:=1 to m do
write(b[i,j]);
writeln
end
end.
Повернутися до списку


Приклад програми.

 program E23;
const
NA=6.23E23;
var
N:integer;
M,R,P,V,K:real;
begin
writeln('Якщо відоме число Авогадро, густина Р');
writeln('цієї речовини і її молярна маса М,');
writeln('то можна знайти кількість молекул в:');
writeln('1. В одиниці маси речовини');
writeln('2. В тілі масою ');
writeln('3. В одиниці об''єму');
writeln('4. В тілі об''ємом ');
write('Введіть номер задачі, що розв''язується');
readln( N );
write('Введіть початкові дані : М=');
readln( M );
case N of
1:
K:=NA / M;
2:
begin
write('R=');
readln( R );
K:=NA *R / M;
end;
3:
begin
write('густина речовини Р=');
readln(P);
write('V=');
readln(V);
K:= NA * P * V / M;
end;
4:
begin
write('густина речовини Р=');
readln(P);
write('V=');
readln(V);
K:=NA * P / V;
end;
end;
writeln('кількість молекул К=',K);
end.
Повернутися до списку


Приклад програми.

 program E24;
var
x,y,i,m:integer;
c:array [1..5] of integer;
procedure NSD;
{заголовок процедури}
var
a,b:integer;
{опис локальних змінних}
begin
a:=x;
b:=y;
{збереження початкових даних}
while a<>b do
if a>b then
a:=a-b
else
b:=b-a;
m:=a
{результат роботи процедури присвоюється
глобальній змінній}
end;
{кінець процедури}
begin
{початок головної програми}
c[1]:=36;
c[2]:=54;
c[3]:=72;
c[4]:=18;
c[5]:=15;
x:= c[1];
for i:=2 to 5 do
begin
y:=c[i];
NSD;
{виклик процедури без параметрів}
x:=x*y div m
{div - ділення націло для цілочислових даних}
end;
writeln('HCK=',x)
end.
Повернутися до списку


Приклад програми.

 program E25;
var
x,y,i,m:integer;
c:array [1..5] of integer;
procedure NSD(a,b:integer;var k:integer);
{заголовок процедури}
begin
while a<>b do
if a>b then
a:=a-b
else
b:=b-a;
k:=a
{значення змінної k - результат роботи процедури}
end;
{кінець процедури}
begin
{початок головної програми}
c[1]:=36;
c[2]:=54;
c[3]:=72;
c[4]:=18;
c[5]:=15;
x:= c[1];
for i:=2 to 5 do
begin
y:=c[i];
NSD(x,y,m);
{виклик процедури без параметрів}
x:=x*y div m
{div - ділення націло для цілочислових даних}
end;
writeln('HCK=',x)
end.
Повернутися до списку


Приклад програми.

 program E26;
const
n=10;
type
R=array [1..n] of real;
var
Y:R;
A,B,C:real;
i:integer;
procedure Stat(X:R; var S,min,max:real);
begin
S:=0;
min:=X[1];
max:=X[1];
for i:=1 to n do
begin
S:=S+x[i];
if x[i]<min then
min:=x[i];
if x[i]>max then
max:=x[i];
end;
S:=S/n;
end;
begin
{головнa програмa}
for i:=1 to n do
read( Y[i]);
Stat( Y, A, B, C );
{виклик процедури}
write('середнє=',A,'найменше=',B);
writeln('найбільше',C)
end.
Повернутися до списку


Приклад програми.

 program E27;
var
x,y,i:integer;
c:array [1..5] of integer;
function NSD(a,b:integer):integer;
{заголовок функції}
begin
while a<>b do
if a>b then
a:=a-b
else
b:=b-a;
NSD:=a
{результат роботи функції присвоюється її імені}
end;
{кінець процедури}
begin
{початок головної програми}
c[1]:=36;
c[2]:=54;
c[3]:=72;
c[4]:=18;
c[5]:=15;
x:= c[1];
for i:=2 to 5 do
begin
y:=c[i];
x:=x*y div NSD(x,y)
end;
writeln('HCK=',x)
end.
Повернутися до списку


Приклад програми.

 program E28;
var
a1,b1,e,y:real;
{a1,b1 - кінці відрізка,
е - точність обчислень, y - результат обчислень}
function f( x : real ):real;
{заголовок функції}
begin
f:=x*x-cos(x)+0.5;
end;
{кінець опису функції}
procedure precise(a,b,eps:real; var c:real);
{процедура уточнення кореня методом ділення
відрізка навпіл}
begin
while abs(b-a)>eps do
begin
c:=(a+b)/2;
if f(a)*f(c)> 0 then
a:=c
else
b:=c
end;
c:=(a+b)/2
end;
{кінець процедури}
begin
{початок головної програми}
write('введіть значення кінців відрізка');
readln(a1,b1);
write('введіть точність');
readln(e);
precise(a1,b1,e,y);
writeln('корінь f(x) на відрізку ',a1,',',b1,'дорівнює ',y)
end.
Повернутися до списку


Приклад програми.

 program E29;
var
n,y:integer;
function F( x : integer ):integer;
{опис рекурсивної функції}
begin
if x= 1 then
F:=1
{виклик для початкового визначення}
else
F:=x*F(x-1);
{виклик для попереднього визначення}
end;
{кінець опису функції}
begin
{початок головної програми}
write('введіть натуральне число не більше 14 n=');
readln(n);
Y:=F(n);
{виклик функції в головній програмі}
writeln(n,'!=',Y)
end.
Повернутися до списку


Приклад програми.

 program E30;
var
y:real;
n:integer;
function power( k : integer; x:real ):real;
{опис рекурсивної функції}
begin
if k=0 then
power:=1
{початковe визначення}
else
power:=x*power(k-1,x);
{рекурсивне визначення}
end;
{кінець опису функції}
begin
{початок головної програми}
write('основа стeпеня x=');
readln(y);
write('показник стапеня k=');
readln(n);
writeln(y,'в степені ',n,'=',power(n,y))
{виклик функції і друкування результату}
end.
Повернутися до списку


Приклад програми.

 program E31;
var
k,kr:integer;
procedure Hanoy(n:integer; One,Two,Three:char);
begin
if n>0 then
begin
Hanoy(n-1,One,Three,Two);
writeln('перемістити диск ',n:2,' зі стержня ', One,' на стержень ',Two);
Hanoy(n-1,Three,Two,One)
end
end;
begin
write('кількість дисків =');
readln(k);
kr:=0;
Hanoy(k,'A','C','B')
end.
Повернутися до списку


Приклад програми.

 program E32;
const
n=15;
var
a,b:array [1..n] of char;
i:integer;
begin
for i:=1 to n do
begin
read(a[i]);
b[n-i+1]:=a[i]
end;
writeln;
for i:=1 to n do
write(b[i])
end.
Повернутися до списку


Приклад програми.

 program E33;
var
x,y:string[20];
k,l,n:integer;
begin
writeln('введіть два рядки');
readln(x);
readln(y);
k:=length(x);
l:=length(y);
n:=length(x+y);
writeln('довжина першого рядка':25, 'довжина другого рядка':25);
writeln(k:25,l:25);
writeln(x+y,'довжина рядка',n)
end.
Повернутися до списку


Приклад програми.

 program E34;
var
x,y:string[10];
i:integer;
begin
writeln('введіть слово');
readln(x);
y:='';
for i:=1 to length(x) do
y:=copy(x,i,1)+y;
writeln;
writeln(y)
end.
Повернутися до списку


Приклад програми.

 program E35;
var
x:string[10];
i:integer;
begin
x:='форма';
insert('i',x,2);
delete(x,3,1);
writeln(x)
end.
Повернутися до списку


Приклад програми.

 program E36;
label 1,2,3;
const
p=10;
{кількість слів у словнику}
var
e,r:array [1..p] of string[10];
x:string[10];
i,k,m,n:integer;
a,b:string;
begin
{формування словників}
writeln('введіть ',p,' англійських слів');
for i:=1 to p do
readln(e[i]);
writeln('введіть українські слова');
for i:=1 to p do
readln(r[i]);
{введення речення і виділення слів з речення}
writeln('введіть речення');
readln(b);
a:=b;
{збереження вихідного речення}
m:=1;
n:=length(a);
{n - довжина речення}
1: k:=pos(' ',a);
{пошук пропуску}
if k=0 then
k:=length(a)+1;
{виставлення пропуску після останнього слова}
x:=copy(a,m,k-m);
{вирізання слова довжиною k-m символів}
if (x='a') or (x='the') then
goto 3;
{обробка артиклів}
{пошук слова в словнику}
for i:=1 to p do
if e[i]=x then
goto 2;
writeln('слова в словнику немає');
goto 3;
2:writeln(r[i]);
{виведення слова з українського словника}
3:k:=k+1;
{перехід до наступного слова в реченні}
a:=copy(a,k,n-k+1);
if a<>'' then
goto 1
end.
Повернутися до списку


Приклад програми.

 Program E37;
function f(x:real):real;
{ обчислення функції f(x)}
begin
f:=sin(x);
end;
Procedure grafic;
var
xmax,ymax,x1,y1:integer;
x,y,a,b:real;
Begin
xmax:=640;
ymax:=480;
a:=-pi;
b:=pi;
for x1:=1 to xmax do
begin
x:=a+x1*(b-a)/xmax;
y:=f(x);
y1:=trunc(y*xmax/(b-a));
y1:=ymax div 2 - y1;
Point(x1,y1);
end
end;
{головна програма}
Begin
grafic;
end.
Повернутися до списку


Приклад програми.

 Program E38;
Begin
Brush(1,255,255,0);
Rectangle(210,160,245,320);
Brush(1,255,0,0);
Rectangle(210+2*35,320-106,210+3*35,320);
Brush(1,0,255,0);
Rectangle(210+4*35,320-53,210+5*35,320);
MoveTo(210,320+30);
Write('Успішність, %')
end.
Повернутися до списку


Приклад програми.

 Program E39;
var
xmax,ymax,x1,y1,x,y,r:integer;
Begin
xmax:=640;
ymax:=480;
for x1:=1 to 125 do
begin
x:=trunc(xmax/2+ymax/2*cos(x1/20));
y:=trunc(ymax/2+xmax/4*sin(x1/20));
r:=trunc(ymax/4-x1);
Ellipse(x-r,y-r,x+r,y+r);
end
end.
Повернутися до списку


Приклад програми.

 Program E40;
Procedure Sektor(kut:integer);
Begin
Line(320,240,320+round(200*cos(kut*pi/180)),240-round(200*sin(kut*pi/180)));
Fill(320+round(198*cos((kut+2)*pi/180)),240-round(198*sin((kut+2)*pi/180)));
end;
Begin
Ellipse(121,41,520,440);
Brush(1,0,255,0);
Sektor(0);
Brush(1,255,0,0);
Sektor(180);
Brush(1,0,0,255);
Sektor(300);
end.
Повернутися до списку


Приклад програми.

 Program E41;
const
n=3;
type
date_of_birth = record
day,month,year : integer
end;
worker = record
name : string[20];
position : string[10];
db : date_of_birth;
salary : real
end;
var
x : array [1..n] of worker;
i,j,g : integer;
S : real;
p : string[10];
begin
{формування масиву записів}
for i:=1 to n do
begin
writeln('відомості про ',i,'-го працівника');
writeln('прізвите, ініціали');
readln(x[i].name);
writeln('посада');
readln(x[i].position);
writeln('число, місяць і рік народження');
readln(x[i].db.day,x[i].db.month,x[i].db.year);
writeln('зарплата');
readln(x[i].salary)
end;
{розвязування задачі 1 - друкування списку бухгалтерів}
p:='бухгалтер';
{лічильник списку - кількість бухгалтерів}
j:=0;
for i:=1 to n do
if p=x[i].position then
begin
j:=j+1;
writeln(j,'.',x[i].name);
{після номера в списку друкується
крапка та імя}
end;
{розвязування задачі 2 - список працівників від 30 до 50 років}
date(g,i,j);
j:=0;
for i:=1 to n do
if (g-x[i].db.year<50) and (g-x[i].db.year>30) then
begin
j:=j+1;
writeln(j,'.',x[i].name);
end;
{розвязування задачі 3 - обчислення середньої зарплати}
S:=0;
for i:=1 to n do
S:=S+x[i].salary;
writeln('середня зарплата =',S/n:10:2);
end.
Повернутися до списку


Приклад програми.

 program E42;
var
f:text;
a,i:integer;
begin
assign(f,'f.dat');
rewrite(f);
writeln('введіть 10 цілих чисел, після кожного');
writeln('натискайте Enter');
for i:=1 to 10 do
begin
readln(a);
writeln(f,a);
end;
close(f);
end.
Повернутися до списку


Приклад програми.

 program E43;
const
k=5;
var
f:text;
a,i,n,p,z:integer;
begin
assign(f,'f.dat');
rewrite(f);
writeln('введіть ',k,' цілих чисел, після кожного');
writeln('натискайте Enter');
for i:=1 to k do
begin
readln(a);
writeln(f,a);
end;
close(f);
{підрахунок різних елементів}
n:=0;
p:=0;
z:=0;
reset(f);
while not eof(f) do
begin
readln(f,a);
if a=0 then
z:=z+1;
if a<0 then
n:=n+1;
if a>0 then
p:=p+1;
end;
close(f);
write('n=',n,' z=',z,' p=',p)
end.
Повернутися до списку


Приклад програми.

 program E44;
const
k=5;
var
f,g:text;
a:integer;
begin
assign(f,'F.DAT');
assign(g,'G.DAT');
{перезапис даних з вихідного файлу в допоміжний}
reset(f);
rewrite(g);
while not eof(f) do
begin
readln(f,a);
writeln(g,a);
end;
close(f);
{додання даних до допоміжного файлу}
readln(a);
{ознака закінчення введення нових даних - нуль}
while a<>0 do
begin
writeln(g,a);
readln(a);
end;
close(g);
reset(g);
rewrite(f);
{перезапис даних назад у вихідний файл}
writeln('модифікований файл');
while not eof(g) do
begin
readln(g,a);
writeln(f,a);
writeln(a);
end;
close(f);
close(g);
end.
Повернутися до списку


Поворот праворуч.

Для того, щоб робот повернувся праворуч, треба звернутись до процедури Направо, яка оголошена наступним чином
Procedure Right ( x : integer );
Процедура Направо ( x : цілі );
 Якщо аргумент не вказаний, то робот повертається на 90 градусів праворуч. При цьому дужки вживати не можна. Якщо вказати аргументом ціле додатнє число, то поворот повторюється задане число разів.
Зверніть увагу, що напрям повороту задається відносно робота, а не відносно спостерігача.

Приклад:
команда
Right (3);
еквівалентна команді
Left ;


Схема складу.

Для унаочнення використання програмування використано модель програмованого робота-вантажника на складі. Модель виконана таким чином, що при потребі можна зробити справжній макет з дистанційним керуванням.

Склад поділено на клітинки, по яких рухається робот. Клітинки нумерують зверху вниз і зліва направо, як показано на малюнку. Є чотири типи клітинок: стіна, вільна, вантаж і помічена. Змінювати початкову конфігурацію складу можна натисканням лівої кнопки мишки у відповідній клітинці. Встановити початкову позицію і напрямок робота можна натисканням правої кнопки мишки. Окремий статус має клітина вихід. Роботу заборонено заходити на цю клітинку, але він може брати з неї і класти на неї необмежену кількість вантажів. Це логічно, тому що робот обслуговує склад, на вхід якого постійно привозять і забирають вантажі.


Синус.

Function Sin ( x : real ) : real;
Фактичним параметром має бути вираз дійсного або цілого типу, який задає кут в радіанах.
Результатом є значенням синуса x і має дійсний тип.