46422

ОСНОВИ ПРОГРАМУВАННЯ ТА АЛГОРИТМІЧНІ МОВИ

Конспект

Информатика, кибернетика и программирование

Приклад слів у програмі: Progrm Input Output Vr Begin Integer WriteLn End. Приклад рядків програми: vr nme : string; begin write‘Як вас звуть’; redlnnme; writeln‘Здрастуйте шановний ’nme’ ’; end. Операції виведення виконують так само дві процедури: Write і WriteLn. Процедура WriteLn аналогічна процедурі Write але після її виконання курсор переміщаєтьсянав початок нового рядка.

Украинкский

2013-11-21

453.93 KB

42 чел.

Міністерство освіти і науки, молоді та спорту України

Запорізький електротехнічний коледж

Запорізького національного технічного університету

ЗАТВЕРДЖЕНО

Протокол засідання ПЦК “Розробка програмного забезпечення”

від _______________2011 № _____

Голова ПЦК _________ Н.В. Бабенко

ОСНОВИ ПРОГРАМУВАННЯ ТА АЛГОРИТМІЧНІ МОВИ

Конспект лекцій для спеціальності

«Розробка програмного забезпечення»

Викладач       І.В. Саєнко 

2011


Конспект лекцій з предмета «Основи програмування та алгоритмічні мови» для студентів денного відділення спеціальності «Розробка програмного забезпечення»  розглянуто на засіданні методичної ради коледжу та рекомендовано для використання у навчальному процесі.

Секретар методичної ради   В.В Кузьменкова

Конспект лекцій з предмета «Основи програмування та алгоритмічні мови» для студентів денного відділення спеціальності «Розробка програмного забезпечення» оформлено згідно з вимогами стандартів коледжу.

Фахівець зі стандартизації   В.О. Білий


Передмова

Конспект лекцій з предмета “Основи програмування та алгоритмічні мови” для студентів денного відділення спеціальності “Розробка програмного забезпечення”. Вищеназваний предмет відноситься до предметів професійно-практичної підготовки навчального плану спеціальності, створеного на основі галузевого стандарту вищої освіти з підготовки молодших спеціалістів за спеціальністю 5.05010301 “Розробка програмного забезпечення”, затвердженого в 2009 р.

Для успішного оволодіння знанням з предмету “Основи програмування та алгоритмічні мови” необхідно мати знання з предметів “Інформатика”, “Математика”.

Знання, які одержать студенти після вивчення предмета, можуть застосовуватися при вивчення предметів “Технологія алгоритмів і структури даних”,“Об’єктно-орієнтоване програмування” а також в курсовому та дипломному проектуванні.

Компетенції, якими повинен оволодіти студент:

  1.  здатність розробляти алгоритми та структури даних для програмних продуктів;
  2.  володіння основами конструювання програмного забезпечення;
  3.  здатність моделювати різні аспекти системи, для якої створюється програмне забеспечення.


Зміст

Вступ 6

Тема 1: Правила техніки безпеки при роботі з комп’ютером 7

Тема 2: Алфавіт. Ідентифікатори. Константи. Вирази 10

Тема 3: Загальна структура і розділи Pascal-програми 13

Тема 4: Введення і виведення у Pascal-і. Форматоване виведення 18

Тема 5: Прості (скалярні) типи данних 22

Тема 6: Завантаження середовища Турбо Паскаль. Функціональні клавіші 29

Тема 7: Меню опції 31

Тема 8: Вираження і пріоритет операцій. Стандартні математичні функції та процедури 37

Тема 9: Умовний оператор. Вкладений умовний оператор 44

Тема 10: Оператор вибору 51

Тема 11: Оператори циклу. Оператор циклу з параметром 53

Тема 12: Оператор циклу з перед- і з постумовою 56

Тема 13: Складні типи. Масиви 60

Тема 14: Багатомірні масиви 67

Тема 15: Пошук і сортування елементів масиву. Класи алгоритмів сортування 70

Тема 16: Динамічна пам'ять. Адреси і покажчики 74

Тема 17: Оголошення покажчиків, виділення та звільнення динамічної пам’яті 76

Тема 18: Процедури та функції для роботи з динамічною пам’яттю 82

Тема 19: Символьний тип даних. Упаковані масиви 85

Тема 20: Процедури та функції для обробки рядків 91

Тема 21: Структурований тип даних - безліч 95

Тема 22: Структурований тип даних – записи 99

Тема 23: Опис файлових змінних. Обробка типізованих файлів 103

Тема 24: Послідовний та прямий доступ до файлів 108

Тема 25: Обробка не типізованих файлів 111

Тема 26: Робота з текстовими файлами 113

Тема 27: Типізовані константи 117

Тема 28: Поняття та робота з процедурами та функціями 120

Тема 29: Використання модуля CRT. Програмування клавіатури 125

Тема 30: Використання модуля CRT. Текстове виведення на екран. Програмування звукового генератора 127

Тема 31: Графічні можливості TP 7.0. Використання бібліотеки Graph 132

Тема 32: Бібліотечні модулі користувача 145

Тема 33: Основні принципи ООП. Створення об’єктів. Використання об’єктів 149

Список літератури 151

Додаток А 152

Основні алгоритми обробки масивів 152

Додаток Б 169

Питання перевірки знань з теорії 169

Додаток Д 175

Коди сканування клавіатури 175


Вступ 

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

Прийнято вважати, що вона хороша для вчення програмуванню. І дійсно, мова Паскаль була створена в кінці 60-х років Ніклаусом Віртом як спеціальна мова для вчення студентів. Проте незабаром із-за реалізації в ній прогресивних ідей того часу набула поширення серед програмістів. Був час, коли Паскаль широко використовувався для написання прикладних програм і навіть як мова системного програмування. Програмне забезпечення багатьох міні- і мікрокомп'ютерів було написано на Pascal.   

Після 70-го року мова Pascal розвивалася і удосконалювалася, включала нові можливості. Вироблялися нові транслятори і середовища розробки для Pascal.  

Транслятори з цієї мови були на найбільш поширених типах ЕОМ у всьому світі. Наявність спеціальних методик створення трансляторів з Паскаля спростила їх розробку і сприяла широкому поширенню мови. Транслятори могли оптимізувати код, і це дозволяло створювати ефективні програми. Це якраз і послужило однією з причин використання Паскаля як мови системного програмування.   

У 80-х роках комп'ютерна наука почала входити в маси, з'явився предмет «Інформатика». Оскільки в цей час Pascal був особливо модним і зарекомендував себе як учбова мова, то він знайшов широке поширення в школах і вузах. У результаті було написано величезну кількість навчальних посібників по цій мові.   

Серед інших достоїнств мови програмування Pascal можна відзначити наступне: простота мови дозволяє швидко її освоїти і створювати алгоритмічно складні програми. Розвинені засоби представлення структур даних забезпечують зручність роботи як з числовою, так з символьною і бітовою інформацією. У мові Паскаль реалізовані ідеї структурного програмування, що робить програму наочною і дає хороші можливості для розробки і відладки.   

Щоб бути простішим, Pascal має деякі обмеження. Так, Паскаль добре «вчить» розуміти, як зберігаються дані в пам'яті комп'ютера, але має ряд обмежень при роботі з ними (чого позбавлені більшість «справжніх» мов).  Оскільки свого часу Паскаль досить активно використовувався для вирішення практичних завдань, на його основі сформувалася мова Object Pascal (яка зараз використовується в Delphi).


Тема 1: Правила техніки безпеки при роботі з комп’ютером

Людина, яка експлуатує засоби обчислювальної техніки і периферійне устаткування може піддаватися небезпечним і шкідливим факторам, які за природою дії підрозділяються на наступні групи:

  1.  поразка електричним струмом;
  2.  механічні пошкодження;
  3.  електромагнітне випромінювання;
  4.  інфрачервоне випромінювання;
  5.  небезпека пожежі.

Для зниження або запобігання впливу небезпечних і шкідливих чинників необхідно дотримувати санітарні правила і норми.

Вимоги електробезпеки.

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

Щоб уникнути поразки електричним струмом необхідно твердо знати і виконувати наступні правила безпечного користування електроенергією:

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

2. Щоб уникнути пошкодження ізоляції дротів і виникнення коротких замикань не дозволяється:

а) вішати що-небудь на дроти;

б) смикати за дроти;

в) висмикувати штепсельну вилку з розетки за шнур, зусилля має бути докладене до корпусу вилки.

3. Для виключення поразки електричним струмом забороняється:

а) часто включати і вимикати комп'ютер без необхідності;

б) торкатися до екрану і до тильної сторони блоків комп'ютера;

в) працювати на засобах обчислювальної техніки і периферійному устаткуванні мокрими руками;

г) працювати на засобах обчислювальної техніки і периферійному устаткуванні, що мають порушення цілісності корпусу, порушення ізоляції дротів, несправну індикацію включення живлення, з ознаками електричної напруги на корпусі;

д) класти на засоби обчислювальної техніки і периферійному устаткуванні сторонні предмети.

є) Забороняється під напругою очищати від пилу і забруднення електроооборудовання.

4. Ремонт електроапаратури проводиться лише фахівцями з дотриманням необхідних технічних вимог.  

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

6. Порятунок пострадавшего при поразці електричним струмом головним чином залежить від прудкості звільнення його від дії струмом.

У всіх випадках поразки людини електричним струмом негайно викликають лікаря. До прибуття лікаря потрібно, не втрачаючи часу, приступити до надання першої допомоги пострадавшему. Необхідно негайно почати робити штучне дихання, найбільш ефективним є метод «рот в рот» або «рот в ніс», а також зовнішній масаж серця. Штучне дихання ураженому електричним струмом робиться аж до прибуття лікаря.

Вимоги по забезпеченню пожежної безпеки

На робочому місці забороняється мати вогненебезпечні речовини. В приміщеннях забороняється:

а) запалювати вогонь;

б) закривати вентиляційні отвори в електроапаратурі  

Приміщення з електроустаткуванням мають бути оснащені вогнегасниками типа ОУ-2 або ОУБ-3.

Для студентів оптимальний час роботи з комп'ютером складає на першому курсі одну годину в день, на старших -дві і три години відповідно, за умови, що робота з відеотерміналом займає не більше 50% всього часу роботи з комп'ютером. Особливо хотілося б підкреслити негативний вплив на здоров'я комп'ютерних ігор з нав'язаним ритмом (тобто ритмом, який гравці не можуть встановити по своєму бажанню). Їх тривалість не повинна перевищувати 10 хвилин для дітей 7-10 років і 15 хвилин для більш старших.  

Гігієністи настійно рекомендують для запобігання стомленню і профілактиці розвитку патологічних відхилень в перервах між заняттями з монітором і після їх закінчення проводити спеціальну зарядку. Існує декілька комплексів вправ для такої зарядки: для очей, для поліпшення мозкового кровообігу, для зняття стомлення з м'язів плечового поясу, рук, тулуба і ніг. Оскільки всі вправи направлені на підвищення насиченості киснем крові і тканин, слід проводити гімнастику в провітреному приміщенні або при відкритих кватирках. Обов'язково робити вправи для очей через кожних 25 хвилин занять, влаштовувати 15-хвилинні перерви з фізкультурними вправами через кожних 45 хвилин роботи.  

Комплекс вправ для очей  

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

1. На рахунок 1-4 зажмурити очі, сильно напружуючи очні м'язи, потім розкрити їх і, розслабивши м'язи, поглянути удалину на рахунок 1-6.   

2. На рахунок 1-4 поглянути на перенісся і затримати погляд. Потім перевести погляд удалину на рахунок 1-6.   

3. На рахунок 1-4, не повертаючи голови, поглянути направо, потім перевести погляд прямо удалину на рахунок 1-6. Те ж саме повторити з фіксацією погляду вгору, вліво і вниз.   

4. Перевести погляд швидко по діагоналі направо вгору - наліво вниз, потім поглянути удалину на рахунок 1-6, потім повторити те ж саме в напрямі наліво вгору - направо вниз.   

Комплекс вправ для поліпшення мозкового кровообігу   

Тривала сидяча робота з фіксованим (особливо з нахилом в один бік) положенням голови приводить до погіршення мозкового кровообігу.

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

1. Вихідне положення - руки уздовж тулуба. На рахунок 1- руки до плечей, стиснути кисті в кулаці, голову нахилити назад; 2 - лікті вгору, голову нахилити вперед; 3 - вихідне положення. Темп середній.   

2. Вихідне положення - руки в сторони. На рахунок 1-3 ривки зігнутими в ліктях руками, правою попереду, лівою за спиною; 4 - повернутися у вихідне положення; 5 - 8 - те ж в інший бік. Темп швидкий.   

3. Вихідне положення - руки уздовж тулуба, голова прямо. На рахунок 1 - голову нахилити управо; 2 - вихідне положення; 3 - голову нахилити вліво; 4 - вихідне положення; 5 - голову обернути управо; 6 - вихідне положення; 7 - голову обернути вліво; 8 - вихідне положення. Темп повільний.


Тема 2: Алфавіт. Ідентифікатори. Константи. Вирази

Мова програмування Pascal розроблена у 1968-71 р. Ніклаусом Виртом у Цюрихском Інституті інформатики (Швейцарія) і названа на честь французького винахідника першої рахункової машини Блеза Паскаля. Призначена для рішення найрізноманітніших задач: обчислювальних, економічних, інформаційних і т.д.

Завдяки своїй простоті, логічності й ефективності, Pascal одержав широке поширення у світі.

Елементами мови є символи, слова й оператори. З послідовності символів утворюються слова, а з комбінації слів – оператори.

Мова має обмежений набір символів і складається з:

  1.  латиниці: від Aa до Zz і пробілу (у коментарях і символьних константах допускаються букви кирилиці);
  2.  арабських цифр: від 0 до 9;
  3.  шістнадцятирічних цифр (арабські цифри від 0 до 9 і латинські букви від Aa до Ff);
  4.  спеціальних символів:

+   -   *   /   =   <   >   .   ,   '   [   ]   (   )   {   }   #   $   ;   :   ^   @

  1.  спарених символів, отриманих комбінаціями спеціальних:

<>   <=   >=   :=   ..   (*   *)   (.   .)

Спарені символи розривати пробілом не можна.

Слова мають визначений сенс і в тексті програми розділяються пробілами чи іншими спеціальними символами.

Приклад слів у програмі:

Program, Input, Output, Var, Begin, Integer, WriteLn, End.

Якщо між словами знаходиться один з наступних роздільників: “+”, “-”, “/”, “*”, “=”, “:”, “;”, “(”, “)”, то пробіл можна ставити до і після роздільника, але можна його і не ставити. Де допускається один пробіл, можна ставити будь-яку кількість пробілів (зайві пробіли ігноруються компілятором). Наприклад, рядок

var a, b, c : integer ;

можна записати так:

var a,b,c:integer;

У Pascal-і маються слова, зміст яких строго фіксований. Називаються вони службовими чи зарезервованими.

Наприклад, Program, Const, Do, Begin, End, Var і інші. Службові слова є складовою частиною мови і їх неможна використовувати для інших цілей, наприклад, в якості імен змінних, констант і т.д.

Крім службових слів у Pascal використовуються два види ідентифікаторів (імен): стандартні і ти, що задає користувач.

Стандартні ідентифікатори закладені в мові для позначення вбудованих об'єктів. Наприклад, Read, Write, Abs, Char, Boolean і т.д.

Ідентифікатори користувача визначаються користувачем і повинні відрізняться від стандартних. Правила їхнього написання наступні:

  1.  ідентифікатор повинний починатися з букви чи знака подчерку і може містити букви, цифри і знак подчерку;
  2.  довжина ідентифікатора до 63 символів;
  3.  ідентифікатор можна писати як рядковими, так і прописними буквами, чи використовувати ті й інші одночасно;
  4.  пробіл в ідентифікаторі неприпустимий.

Приклади написання ідентифікаторів.

Вірно:   Невірно:

My_Program  My Program         -пробіл;

Name_2   2_Name          -починається з цифри;

Primer5   End           -службове слово;

Dlina   (Dlina)          -круглі дужки;

Kmh    Km/h           -похила риса;

Uslovie4   Uslovie-4          -тире.

Для пояснень у програмі пишуть коментарі, що робить її більш зрозумілою.

Коментар – це послідовність будь-яких символів, що маються на клавіатурі, укладена у фігурні дужки “{” і “}” чи в роздільники “(*” і ”*)”, що є його ознакою.

Коментар ігнорується компілятором і тому його можна вставляти в будь-яке місце програми, де використовується пробіл. Наприклад, даний запис

 var a, {перший елемент добутку} b, {другий елемент добутку}

 res : {результат} integer;

рівнозначна запису

 var

 a, {перший елемент добутку}

b, {другий елемент добутку}

res : integer; {результат}

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

 

{Короткий коментар пишуть в одному рядку}

{Довгий коментар потрібно

писати в кілька рядків}

Слова в Pascal-програмі утворять рядок, довжина якого не повинна перевищувати 126 символів. Приклад рядків програми:

var

name : string;

begin

write(‘Як вас звуть?’);

readln(name);

writeln(‘Здрастуйте, шановний ’,name,’ !’);

end.

Рядок, що не вміщується на екрані, краще перенести, наприклад:

wrineln(‘Здрастуйте, шановний ‘,

name,’ !’);

При переносі потрібно стежити, щоб знаки не повторювалися.

У Pascal-програмі використовують десяткові і цілі шістнадцятирічні числа. Десяткові числа можуть бути представлені з фіксованою і десятковою плаваючою крапкою. Технічне позначення Е потрібно читати як “десять у ступені”. Наприклад:

7Е-2  “7 помножене на 10 у ступені -2”

тобто 7Е-2=7*10-2;  

12.25Е6  “12.25 помножене на 10 у ступені +6”

тобто 12.25Е6=12.25*106

Запис шістнадцятирічного числа повинна починатся зі знаку долара ($). Наприклад: $7А.

Питання для контролю:

  1.  Хто створив мову Pascal?
  2.  Які елементи мови Pascal ви знаєте?
  3.  Назвіть роздільники слів. Як у словах використовується пробіл?
  4.  Чи можна ставити пробіл між спареними символами?
  5.  Що таке службові слова?
  6.  Які ідентифікатори бувають у Pascal-і? Назвіть правила написання ідентифікаторів.
  7.  Що таке коментар і для чого він потрібний?
  8.  Де в програмі можна писати коментар?
  9.  Яка довжина рядка в Pascal-програмі?
  10.  Чи можна переносити рядок у Pascal-програмі? Якщо так, то як це робиться?
  11.  Які числа використовують у Pascal-программе?
  12.  Як зображуються числа з десятковою крапкою і числа шістнадцятирічні?


Тема 3: Загальна структура і розділи Pascal-програми

Синтаксично програма представляється з необов'язкового заголовка і глобального блоку, що складається з двох частин: описової і виконавчої. Глобальний блок може містити локальні блоки – це процедури і функції. Об'єкти програми (типи, змінні, константи і т.д.) відповідно називаються глобальними і локальними. Область дії об'єктів – блок, де вони описані, і усі вкладені в нього блоки.

Загальний вид структури Pascal-програми:

рrogram ім'я програми (input, output);

Розділ описів:

{&…}; {директиви компілятора}

uses…; {підключення бібліотечних модулів}

label…; {розділ оголошення міток}

const…; {розділ опису констант}

type…; {розділ опису типів}

var…; {розділ опису змінних}

Розділ процедур і функцій:

procedure (function) {Ім'я процедури чи функції}

label…; {розділ оголошення міток}

const…; {розділ опису констант}

type…; {розділ опису типів}

var…; {розділ опису змінних}

begin

Оператори тіла процедури чи функції;

end;

Розділ операторів:

begin

Оператори програми;

еnd.

Заголовок містить службове слово Program, ім'я програми й у круглих дужках параметри Input і Output для зв'язку ПК зі стандартними зовнішніми пристроями. Пристроєм введення – Input – є клавіатура, а пристроєм виведення – Output – монітор. Наприкінці заголовка ставиться “;”. Перед заголовком можна писати коментар. Приклад заголовка:

{Знаходження суми перших n-членів рядка}

program My_progrSum (input, output);

Ім'я програми задає користувач. У Turbo Pascal-і заголовок можна опускати.

Після заголовкі слідує розділ описів, призначений для оголошення всіх існуючих в програмі даних і їхніх характеристик. Він може включати оголошення директив компілятора, розділи оголошень міток, описів констант, типів і змінних. Кожен опис закінчується “;”.

Усі дані, використовувані в розділі операторів, повинні попередньо бути описані (оголошені), інакше, при трансляції, у місці неописаного об'єкта буде вироблена помилка й обробка програми припиниться.

Будь-який з зазначених розділів, крім операторів основної програми, може бути відсутній (у простій програмі розділ описів взагалі може бути відсутній).

Послідовність розділів Label, Const, Type і Var може бути довільною.

Директиви компілятора – це інструкції, що задають той чи інший режим компіляції програми з метою одержання найбільш ефективного коду. Ознакою директиви є символ $, записаний без пробілу після першої фігурної дужки, за яким йде буква, що визначає режим компіляції. Знак “+” за буквою задає даний режим, а “-” – його скасовує. Наприклад: {$R-}. Якщо задають кілька директив, їх розділяють комами. Наприклад:

{$N+,K-,R+}

Розділ Uses підключає до тексту програми стандартні і користувальницькі бібліотечні модулі. Для підключення потрібно після Uses перелічити через кому імена модулів. Наприкінці списку ставиться “;”.

Наприклад:

 

uses Crt, Graph, My_Lib;

Розділ оголошення міток починається зі службового слова Label (мітка), за яким через кому слідують імена міток. Наприкінці ставиться “;”.Наприклад:

 

label {ключове слово}

 ім'я_мітки_1, ім'я_мітки_2,…;

Мітку можна поставити перед будь-яким оператором, що дозволяє виконати перехід на цей оператор за допомогою оператора Goto з будь-якого місця програмного блоку. У розділі операторів ознакою мітки для компілятора є наявність після її імені двокрапки.

Якщо оголошена мітка не використовується, помилки не буде.

Розділ опису констант починається зі службового слова Const (Constant – постійна величина), за яким слідує ім'я константи, якії за допомогою символу “=” привласнюється постійне числове чи строкове значення:

const {ключове слово}

ім'я_константи = числове вираження;

В одному розділі можна описувати кілька констант. Кожен опис закінчується “;”, а слово Const для наочності програми варто виділяти в окремий рядок, наприклад:

const

a = 50; n1 = 0;

Якщо константа задана явно, тобто своїм значенням, то її описувати не потрібно. Наприклад:

ord(‘Z’) – ord(‘A’) + 1 {тут 1 – константа задана явно}

У ТР можна використовувати константні вираження, тобто вираження, що можуть бути обчислені компілятором фактично без виконання програми. Наприклад:

 

256 - 1;

(2,5+1)/(2,5-1);

‘Turbo’ + ‘’+’ Pascal’

chr(32)

Розділ опису типів починається зі службового слова Type, за яким слідують одне чи кілька визначень типів, розділених ";".Опис типів має загальний вид:

type

ім'я типу 1, ім'я типу 2,... = стандартне чи раніше описане ім'я типу;

. . .

Наприклад:

type

massiv = array[1...20] of integer;

name= string[10];

Розділ опису змінних починається зі службового слова Var (Variables - змінна), за яким слідує ім'я змінної і через двокрапку вказується тип. Наприкінці типу ставиться ";".

var

ім'я змінної : тип змінної;

В одному розділі можна описувати декілька змінних. Якщо ряд змінних мають один тип, їх можна об'єднати в список. У списку змінні розділять комами. Слово Var варто виділяти в окремий рядок, наприклад:

var

a,b,c : integer;

result: real;

Це робить текст програми більш зрозумілим.

Розділ процедур і функцій. У Paskal процедури і функції виконують роль підпрограм і мають ту ж структуру, що і програма, але замість ключового слова program повинне бути слово procedure чи function. Процедури і функції поділяються на стандартні та ті, що визначаються користувачем.

Стандартні процедури і функції заздалегідь створені, є частиною мови і можуть викликатися без попереднього опису. Зберігаються вони в бібліотеках Pascal.

Користувач може створювати свої додаткові процедури і функції, що обов'язково описуються в розділі процедур і функцій.

Розділ операторів. Опис операторів уявляє собою складений оператор begin (початок) ...end.(кінець), що закінчується крапкою та у якому розташована вся послідовність операторів програми, розділених ";":

begin

Оператор 1;

Оператор 2;

. . .

end.

Оператори програми також можуть бути включені в операторні дужки begin ... end для внесення ясності, де потрібно ставити ";", розглянемо список елементів, записаних натуральною мовою:

A, B, C, D.

Запис не зміниться, якщо елементи списку об'єднати в групу, уклавши її в круглі дужки:

(A, B, C, D).

Тепер представимо кілька подібних груп:

(A, B, C, D).

Е.

(ДО, L, M).

Об'єднаємо їх в одну загальну групу, дотримуючи правил натуральної мови:

((A, B, C, D), Е, (K, L, M)).

Аналогічні правила й у мові Pascal, тільки роль круглих дужок виконують операторні дужки begin і end, замість коми ставиться ";", а замість елементів - оператори.

Замінивши в приведеному записі круглі дужки відповідно на begin і end, коми на “;”, елементи на оператори, ми її представимо записаною мовою Pascal (для кращої наочності тексту програми кожен елемент запишемо в окремому рядку):

begin

begin

оператор А;

оператор ;

оператор ;

оператор ;

end;

Е;

begin

оператор ;

оператор ;

оператор ;

end

end.

Крапка наприкінці програми обов'язкова - вона є для компілятора ознакою кінця програми.

Як у природній мові після і перед круглими дужками кома не ставиться, так і в мові Pascal після Begin і перед  End ";" не ставиться.

Питання для контролю.

  1.  З яких розділів складається Pascal -програма? Які розділи можуть бути відсутніми у програмі?
  2.  Яке призначення розділу описів?
  3.  Що містить заголовок Pascal-програми?
  4.  Що таке директиви компілятора? Ознака директиви.
  5.  Яке призначення розділу Uses?
  6.  Що таке мітка і як вона з'являється?
  7.  Як описується константа? В якому випадку константу не описують?
  8.  Що таке константне вираження?
  9.  Чи можна в одному розділі описувати кілька констант? Оголошувати кілька міток?
  10.  Яка послідовність розділів Label, Const, Type і Var?
  11.  Яке призначення в заголовку параметрів Input і Output?
  12.  Як оголошується змінна?
  13.  Опишіть структуру розділу опису типів.
  14.  Чи можна в одному розділі оголосити декілька змінних?
  15.  Опишіть структуру розділу процедур і функцій.
  16.  Опишіть структуру розділу операторів.
  17.  Де потрібно ставити ";" а де ні?
  18.  Яке призначення крапки наприкінці програми?


Тема 4: Введення і виведення у Pascal-і. Форматоване виведення

Операції введення в Pascal-і виконують дві процедури: Read   і ReadLn, що забезпечують введення з клавіатури даних.

Імена змінних, що вводяться у списку розділяються комами, а сам список заключають в круглі дужки. Наприклад,

read (x1,x2,...xn);

де Х1,Х2,...Хn - змінні, які послідовно приймають ті значення, що вводяться з клавіатури. Дані для змінних вводяться після запуску програми на виконання. При цьому, на екрані з'явиться курсор і процедура Read буде чекати введення значень. Значення, що вводяться, відображаються на екрані монітора.

Якщо мається кілька значень, то їх вводять по одному, натискаючи після кожного введеного значення Enter, або розділяючи кожне значення пробілом (але не комою!), а потім натискають Enter.

Розглянемо приклад введення трьох числових значень для змінних А=3, У=-5, З=7.

Процедура введення буде наступною:

read (a,b,c);

Усі три числові значення набираємо на клавіатурі, розділяючи їх пробілами:

3 -5  7 і натискаємо Enter,

чи

3 і натиснути Enter

-5 і натиснути Enter

7 і натиснути Enter

Процедура ReadLn відрізняється від процедури Read тим, що при зчитуванні значень усіх змінних однієі процедури ReadLn значення для наступної процедури ReadLn будуть зчитуватися з початку нового рядка.

Приклад введення числових даних:

Процедура:   Дії, що виконуються:

ReadLn (a,b);   3 -5 Enter;

ReadLn (c);   7 Enter;

ReadLn (d);   8.34 Enter;  

Read (e, f);    -4.76 Enter;

Read (g);    3.35 Enter;

Read (h);    -0.56 Enter;

У цьому прикладі значення можна вводити і по одному, кожне з нового рядка.

Операції виведення виконують так само дві процедури: Write і WriteLn. Вони здійснюють виведення числових даних, символів, рядків і булевих значень.

Процедура  WriteLn  аналогічна  процедурі  Write, але  після  її виконання курсор переміщаєтьсянав початок нового рядка. Формат запису:

write( x1, x2, ...xn,‘фіксований текст‘);

Тут - Х1,Х2 і т.д., результати виконання вираження і змінних; фіксований текст - це текст пояснень, що друкується точно таким, як він введений. Фіксований текст повинен заключатися в апострофи:

writeln (‘Сума чисел ‘, х1, х2 ‘та’ , х3, ‘дорівнює:’, Sum );

writeln ('Кінотеатр "Космос" ');

Для друку самого апострофа його потрібно повторити два рази:

writeln (‘Об’’єм призми = ,’ Vpris);

Процедура WriteLn без параметрів друкує порожній рядок. Наприклад:

writeln (‘Значення А=’, А); writeln;

writeln (‘Значення В=’, B);

У процедурі Write можна виконувати форматоване виведення даних. Для цього, у списку після імені змінної чи вираження через двокрапку вказують ширину поля виведення. Наприклад:

write (y1 : 5, sum : 8);

Тут для виведення результату буде відведене поле в 5 місць, а для результату Sum - 8 знакомісць. Якщо результат - речовинне число, то ширину поля задають для цілої і дробової частини числа:

write (res : 6 : 3);

У цьому випадку виведене на екран число буде займати шість позицій, у тому числі з трьома значеннями після десяткової крапки. З огляду на те, що одну позицію займає десяткова крапка, для  виведення цілої частини числа залишається  6-3-1=2 позиції.

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

writeln (a : 4 :2);

де для виведення цілої частини числа залишається 4-2-1=1 позиція, а число насправді має тризначну цілу частину, наприклад, 327,43. У цьому випадку помилки не буде - ціла частина числа, усупереч зазначеному формату, буде виведена на екран цілком.

Розглянемо приклади завдання форматів.

Якщо не зазначений формат виведеного числа, воно буде виводитися  в експонентній формі.

write (655.456)= 6.5545600000E+2

Тут 6,5545600000- мантиса числа з плаваючою крапкою, яка завжди складається з цілої частини, крапки і 10 знаків після неї, що визначає точність числа (точність залежить від типу ЕОМ), за якими йде технічне Е и порядок. Ціла частина мантиси - завжди зображується однією цифрою.

Якщо у форматі не зазначена кількість позицій для дробової частини, вона буде виводитися в експонентній формі з достатнім для точного зображення числом позицій:

write(655.456 : 1) = 6.6E+02

write(655.456 : 5) = 6.6E+02

Якщо у виведеного числа дробова частина не укладається в кількість відведених для неї позицій , то число округляється (саме ж значення змінної в пам'яті залишається без змін):

write(655.456 : 3 : 1) = 655.5

Якщо для цілої частини відведений нуль позицій, чи недостатня кількість, то ціла частина все рівно буде виведена цілком:

write(655.456 : 0 : 3) = 655.456

write(655.456 : 2 : 3) = 655.456

Для виведення цілої частини числа без її дробової частини і без експоненти, потрібно у форматі відвести для дробової частини нуль позицій:

write(655.456 : 3 : 0) = 655

Ціла частина виведеного числа в цьому випадку округляється, наприклад:

write(655.556 : 3 : 0) = 656

Форматоване виведення обов'язково потрібно застосовувати при виведенні в одному рядку двох і більш результатів:

writeln(x1 : 4, x2 : 4, sum : 6);

При виведенні на екран цілих чисел, наприклад:

writeln(17,22,341) = 1722341 , тобто результати злилися .

Щоб подібне не трапилось, потрібно виведення 2-го і 3-го числа задати у форматі, де вказати кількість позицій більше, ніж кількість цифр у цих числах. Наприклад:

writeln(17,22:3,341:4) = 17 22 341

Можна вивести ці числа в кожному рядку окремо:

writeln(17);

writeln(22);

writeln(341);

але при цьому, тричі приходиться використовувати процедуру WriteLn.

Замість використання формату для поділу результатів можна застосовувати і пробіли:

writeln(res1,’ ‘,res2);

Питання для контролю:

  1.  Яким чином виконуються операції введення даних у Pascal?
  2.  Як виконуються операції виведення даних у Pascal?
  3.  Як записуються імена вводимих змінних?
  4.  Чим відрізняються процедури ReadLn від Read; WriteLn від Write?
  5.  Коли вводяться дані в програму?
  6.  Як варто вводити значення декількох даних?
  7.  Чи можна в процедурі Read використовувати фіксований текст?
  8.  Що, де і як вказується в процедурі Write для організації форматованого виведення?
  9.  Якщо для цілої частини числа відведений нуль позицій, то ...?
  10.  Якщо для дробової частини числа відведений нуль позицій, то ...?
  11.  Крім форматованого виведення як можна розділити дані?
  12.  Що потрібно зробити для виведення результатів на принтер?
  13.  Що виводить процедура WriteLn без параметрів?


Тема 5: Прості (скалярні) типи данних 

Типи даних у мові Pascal. Запущена в роботу програма обробляє деякі дані. Це можуть бути цілі числа, дробу, символи, рядки, масиви, безлічі і т.д. Усі вони відрізняються друг від друга своїм типом.

Тип даних визначає можливі значення констант, змінних, функцій, виражень, а так само операції, що можуть виконаються над ними.

У Pascal усі типи даних поділяються на прості (скалярні) і складні (структуровані) (див. рис. 5.1).

ТИПИ ДАНИХ

Прості (скалярні)

Стандартні

Цілочислені

Речовинні

Символьні

Логічні (Булеві)

Нестандартні

Перераховуємі

Интервальні (обмежені)

Складні (структуровані)

Масив

Запис

Безліч

Файл


Рисунок 5.1. Типи даних мови Турбо Паскаль

У Pascal-І кожен тип описується своїм стандартним ідентифікатором, наприклад, для цілих чисел - Integer, для дробових - Real і т.д. Але користувач може створювати свій, нестандартний тип даних і давати йому довільне ім'я. Нестандартний тип даних обов'язково описується розділі Турe.

Усі дані в програмі інтерпретуються як константи чи як змінні.

Константа не змінює свого значення в процесі виконання програми. Змінна змінює своє значення в ході виконання програми.

Прості(скалярні) типи даних є основою, на якій будуються всі інші структури даних. Скалярні типи поділяються на стандартні, до яких відносяться дані цілочисленого, речовинного, символьного і булевого типу, і нестандартні, до яких відносяться дані интервального  типу і типу, що перелічується.

Дані цілочисленого типу. До них відносяться константи і змінні. Константа цілочисленого типу – це десяткове число, записане без крапки. Якщо константа негативна, то перед нею повинний стояти знак «-», якщо позитивна – те знак «+», який можна не вказувати. Константа, позначена ім'ям, обов'язково повинна бути описана в розділі Const, наприклад:

const

a=27;

radius=127;

Змінна цілочисленого типу приймає значення цілого десяткового числа. Змінна обов'язково повинна бути описана в розділі Var, наприклад:

var

b: integer;

У Pascal-і використовується 5 цілочислених типів, що відрізняються одне від одного діапазоном прийнятих значень і розміром займаної пам'яті (таблиця 5.1).

Таблиця 5.1. Цілочисельні типи мови Турбо Паскаль

Тип

Діапазон

Розмір пам'яті (байт)

Пояснення

Byte

Word

Integer

Shortint

Longint

0..255

0..65535

-32768..32768

-128..128

-2147483648..2147483647

1

2

2

1

4

Довжиною в байт

Довжиною в слово

Ціле

Коротке ціле

Довге ціле

Наприклад:

var

x:integer;

y:byte;

sum, x, y:logint;

Над цілочисленими даними припустимі наступні арифметичні операції:

+  Додавання (результат – ціле число);

-  Вирахування (результат – ціле число);

*  Множення (результат – ціле число);

Div  Одержання цілого частки при діленні цілих чисел (дробова частина при розподілі відкидається);

Mod  Одержання цілого залишку при діленні цілих чисел.

Застосовуючи операцію mod можна:

  1.  визначити, чи є дане число парним, тобто чи поділяється воно на 2 без залишку;
  2.  обчислити залишок при розподілі двох цілих чисел;
  3.  визначити, чи кратне дане число трьом, чотирьом і т.д.
  4.  визначити, чи є дане число простим.

Наприклад, дані А=-8, У=16, З=5, тоді:

Дії  Результат Дії  Результат

А-32       -40 b mod a         0

A+B         8 a mod c        -3

A*c       -40 a div c        -1

A div 5        -1 16 div –3        -5

A mod 5        -3 16 mod –3         1      

Дані речовинного типу.

До даних речовинного типу відносяться константи і змінні.

Константа речовинного типу може бути представлена в двох видах: числом з фіксованою і з плавоючою крапкою.

Число з фіксованою крапкою – це десяткове число з дробовою частиною, що відділена від цілої частини крапкою. Дробова частина може дорівнювати нулю. Наприклад:

21,342;  65,0; -87,767; 2,00; 0,0453;

Речовинне число не може починатися з крапки і не може нею закінчуватися. Наприклад, запису 5, і ,5 неприпустимі. Число 0 – ціле, а число 0,0 – речовинне.

У математиці для зображення дуже великих і дуже маленьких чисел використовується запис числа з десятковим порядком. Наприклад, числа 1200000000 і 0,00000012 можна записати відповідно у виді 12*108 і 12*10-8.

У Paskal-і подібні числа зображуються в експонентній формі і мають вид mEp, де m називається мантисою, а p – порядком числа. Символ Е є ознакою запису числа в десятковому порядку.

Мантиса може бути представлена цілим чи речовинним числом з фіксованою крапкою. Порядок тільки ціле число. Мантиса і порядок можуть містити знаки “+” чи “-”.

Числа, представлені з порядком, називаються числами з плаваючою крапкою. Наприклад:

Математичний запис    Запис на Paskal-і

2*106      2Е+6 чи 2Е6

-2,7*103      -2,7Е3;

0,76*10-3      076Е-3;

-13*10-7      -13Е-7

У будь-якіму приведеному числі можна переміщати десяткову крапку в мантисі й одночасно змінювати порядок (крапка “пливе”), від цього саме число не зміниться. Наприклад:

-2,7Е3 -27Е2  -270Е1  -2700Е0 -27000Е-1.

Змінна речовинного типу приймає значення числа з фіксованою чи плаваючою крапкою.

У Paskal-і використовується 5 речовинних типів, що відрізняються одне від одного діапазоном прийнятих значень і розміром пам'яті (таблиця 5.2).

Таблиця 5.2. Речовинні типи мови Турбо Паскаль

Тип

Діапазон

Мантиса

Розмір (байт)

Пояснення

Real

Single

double

extended

comp

2,9Е-39..1,7Е38

1,5Е-45..3,4Е38

5,0Е-324..1,7Е308

3,4Е-4932..1,1Е4932

-9,2Е18..9,2Е18

11 – 12

7 – 8

15 – 16

19 – 20

19 - 20

6

4

8

10

8

Речовинний

Одинар.точн.

Двоичн.точн.

Повыш.точн.

складний

Ми в обчисленнях будемо використовувати тип Real. Використання інших типів вимагає наявності в ПК математичного співпроцесора. Якщо він є, то необхідно в програмі установити директиву компілятора {$N+}, якщо його немає – директиву програмної эмуляции співпроцесора {$E+}.

Над даними речовинного типу припустимі наступні арифметичні операції:

+ додавання, - вирахування, * множення, / ділення.

Якщо обидва операнда речовинного типу, чи один з них цілого типу, результат операції завжди буде речовинного типу.

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

a+b*c;  a/b+c+56;  sin(a+b+c);

a*b*c;  sqr(a+b/c);  sgrt(a*b+c+0.54).

У Pascal немає операції зведення в ступінь, крім зведення в квадрат. При зведенні в ступінь використовують стандартні функції. Наприклад, Ax заміняють вираженням

Exp(x*ln(a)),

де Exp – експонента і ln – натуральний логарифм – убудовані функції. Значення А повинне бути>0.

Дані логічного типу

Дані логічного типу використовуються при порівнянні величин. Наприклад:

x2 < 0;  вираження завжди неправдиве;

a < b;  вираження правдиве при а=5 і b=3;

  неправдиве при a=3 і b=5.

Результат порівняння може бути або правдивим, або неправдивим.

Значення логічного типу в Pascal-і позначаються убудованими ідентифікаторами констант True (істина) і False (неправда). Їх можна використовувати в явному виді чи позначати ім'ям у розділі Const, наприклад:

const

t = true;

f = false;

Логічна змінна може приймати значення True чи False. Описується логічна змінна в розділі Var ключовим словом Boolean (логічний), наприклад:

var

a : boolean;

b1 : boolean;

У розділі операторів такій змінній можна привласнити значення логічної константи, наприклад:

а := true; b1 := false;

У Pascal-і для порівняння даних передбачені операції відношення(таблиця 5.3).

Таблиця 5.3. Операції відношення

Операції

Дія

Вираження

Результат

=

<>

>

<

>=

<=

in

Дорівнює

Не дорівнює

Більше

Менше

більше чи дорівнює

менше чи дорівнює

Приналежність

A = B

A<>B

A > B

A < B

A >= B

A <= B

A in B

True, A=B

True, A<>B

True, A>B

True, A<B

True, A>=B

True, A<=B

True, якщо А знаходиться в списку В

Порівнюються будь-які типи даних. Результат завжди булевого типу. Наприклад:

4 > 6  дає результат False;

A <> B  дає результат True при А=5 і В=7;

A = 2*B+5  дає результат False при А=10 і В=2.

Відношення можна використовувати в правій частині оператора присвоювання, наприклад:

var

log1,log2: boolean;

log1:=a<>b;

log2:=a=2*b+5;

Змінна log1 одержить значення True, а змінна log2 – значення False.

У Pascal-і, як і в математичній логіці, маються спеціальні логічні операції. Результатом виконання логічних операцій є логічне значення True чи False. Операндами служать дані типу boolean. Операції наведено в таблиці 5.4.

Таблиця 5.4. Логічні операції мови Турбо Паскаль

Опера-ції

Дія

Вираження

А        В

Резуль-тат

Not

Унарна операція інверсії всіх битів цілого числа

not A

T

F

F

T

And

Логічне заперечення. Побітова логічна операція “І” двох цілих чисел

A and B

T         T

T         F

F         T

F         F  

T

F

F
F

Or

Побітова логічна операція “ЧИ” двох цілих чисел

A or B

T         T

T         F

F         T

F         F

T

T

T

F

Xor

Побітова логічна операція “виключення чи” двох цілих чисел

A xor B

T         T

T         F

F         T

F         F

F

T

T

F

   

Приведемо приклади.

Результат операції логічного додавання

(a > 5) or (c = 3)

  1.  неправдивий при А=2, З=1;
  2.  правдивий при А=6, З=3; А=2, З=3; А=7, З=4.

Результат операції логічного множення

(a>5) and (c=3)

  1.  неправдивий при А=2, З=1; А=2, З=3; А=7, З=4;
  2.  правдивий при А=6, З=3.

Результат операції логічного заперечення

not (c=3)

  1.  неправдивий при З=3;
  2.  правдивий при З=4.

Якщо True відповідає 1, а False відповідає 0, то True > False.

Розглянемо приклади виконання логічних операцій з операндами типу Word. Наприклад, дано А та В – типу Word:

A = $5555 = 01010101010101012

B = $00EF = 00000000011111112

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

а and b = 00000000010101012

Побітове порівняння виконується в такий спосіб.

Записуємо в стовпчик біти значень А та В:

А = 01010101010101012

У = 00000000011111112

Починаючи зправа, по одному виписуємо біти з цих значень і виконуємо 0 and 1 = 0

Порівнюючи в такий спосіб усі біти двох значень А та В, одержимо результат 00000000010101012

Аналогічно вирішуємо наступні приклади:

a оr b = 010101010111111

a xor b = 01010101001010102

Оператор Not реверсує значення кожного біта свого операнда:

not b = 11111111100000002

Питання для контролю.

  1.  Що визначає тип даних у Paskal-і?
  2.  На які типи поділяються дані?
  3.  Перелічите прості типи даних.
  4.  Перелічите складні типи даних.
  5.  Назвіть стандартні і нестандартні типи даних.
  6.  Як описуються типи даних у Paskal-і?
  7.  Як інтерпретуються дані в програмі?
  8.  Назвіть дані цілочисленого типу.
  9.  Які арифметичні операції виконуються над даними цілочисельного типу?
  10.  Як може бути представлена константа речовинного типу?
  11.  Чи може речовинне число починатися з крапки чи закінчуватися нею?
  12.  Розповісти про експонентну форму представлення речовинного числа.
  13.  Перелічите речовинні типи даних, застосовувані в Pascal.
  14.  У якому випадку і які директиви компілятору необхідно установити в програмі при обробці даних речовинного типу?
  15.  Перелічите арифметичні операції над даними речовинного типу.
  16.  Як виконуються в Pascal операції зведення в ступінь?
  17.  Як використовуються дані логічного типу?
  18.  Як позначаються значення логічного типу?
  19.  Логічна константа і її використання в програмі.
  20.  Логічна змінна і її використання в програмі.
  21.  Назвіть операції відношення.
  22.  Як відношення використовуються в операторі присвоювання?
  23.  Перелічте логічні операції.
  24.  Що більше: True чи False?


Тема 6: Завантаження середовища Турбо Паскаль. Функціональні клавіші

Середовище програмування  - це пакет програм, призначений для створення вихідних текстів програм і перетворення їх у машинні коди для даного комп'ютера.

Таким середовищем у нас є інтегроване середовище розроблювача – IDE (Integrated Development Environment, файл tpx.exe), Turbo Pascal-ю версії 7.0 фірми Borland International (США).

Складається воно з убудованого компілятора, отладчика і текстового редактора (файл turbo.exe), зовнішніх бібліотек (файл tur-bo.tpl,graph.tpu) і файлу допомоги (turbo.hlp).

IDE має довідкову систему (кл.F1), що видає контекстно-залежну довідку , тобто, можна одержати інформацію про об'єкт, на який вказує курсор чи вибрати курсором в тексті довідки відмічений підсвічуванням елемент для одержання більш докладної інформації.

Виклик IDE виконується запуском файлу turbo.exe, що знаходиться в директорії, набравши в командному рядку DOS:

tp\bin\turbo

Головне меню має наступні секції:

-File. Завантаження існуючих і створення нових файлів, тимчасовий вихід у DOS, збереження файлів на диску і вихід із ТР

-Edit. Редагування вихідних текстів програм, використовуючи блокові команди і послуги вікна Clipboard;

-Search. Команди пошуку і заміни фрагментів тексту, пошуку процедур і місця розташування помилок у програмі;

-Run. Запуск програми на виконання чи покрокове її налагодження;

-Compile. Компіляція поточної програми;

-Debug. Команди отладчика, що дозволяють виконувати налагодження програми (пошук помилок і т.д.) ;

-Tools. Команди повідомлень при налагодженні і список програм, які можна виконати не виходячи з ТР;

-Options. Установка параметрів роботи інтегрованого середовища і компілятора;

-Window. Команди керування вікнами;

-Help. Одержання підказки системи.

Меню цих секцій називаються підлеглими, тому що вони містять свої меню, у які ввійти можна двома способами:

  1.  натиснути F10, рамку вибору навести на потрібне ім'я секції і натиснути Enter.
  2.  більш швидкий спосіб. Натиснути Alt і ,не відпускаючи її, клацнути по клавіші, на якій зображена перша буква імені секції(використання так званих “гарячих” клавіш – Hot Keys).

Вихід з головного чи меню чи меню секції – Esc.         

Крім цього є локальне меню, що містить найбільш часто використовувані команди. Його виклик – Alt+F10 чи натискання правої кнопки миші.

Унизу вікна розташований рядок стану, де зазначені команди і комбінації клавіш, виклик яких виконується не входячи в головне меню.

Закінчення роботи і вихід з IDE – Alt+X.

При роботі в IDE використовуються наступні основні команди:

-F1 – виклик контекстно-залежної підказки;

-F2 – запис вихідної програми з поточним ім'ям;

-F3 – читання файлу з зовнішнього носія ;

-F4 – виконати програму до рядка, де знаходиться курсор;

-F5 – змінити розміри активного вікна;

-F6 – переключити активне вікно;

-F7 – трасування програми;

-F8 – покрокове виконання програми;

-F9 – скомпілювати програму;

-F10 – вхід у головне меню;

-Alt+Цифра – перехід до вікна з зазначеним номером;

-Alt+F3 – закрити поточне (активне) вікно;

-Ctrl+F9 – компіляція і запуск поточної програми на виконання під керуванням IDE;

-Alt+F9 – компіляція програми з активного вікна без її виконання (створення EXE-файлу);

-Alt+F5 – забрати вікно IDE, щоб побачити результати виконання програми. При повторенні цієї команди вікно відновлюється (відновити можна натисканням будь-якої кл.).

Питання для контролю.

1. Що таке середовище програмування і її назва в ТР 7.0?

2. З чого складається IDE, виклик IDE і вихід з нього?

3. Де розташоване головне меню? Назвіть його секції.

4. Як ввійти в меню секцій?

5.Що містить локальне меню і як його відкрити?

6. Де розташовано і що містить рядок стану?

7. Що таке контекстно-залежна підказка і як її викликати?

8. Як записати текст вихідної програми?

9. Як виконати програму під керування IDE?

10.Як побачити результати виконання програми?


Тема 7: Меню опції

Секція File.

Секція File має наступні команди (табл. 7.1).

Таблиця 7.1. Команди секції File

Команда

Функціональна клавіша

Дія

New

Відкриває нове вікно

Open

F3

Відкриває старий файл

Save

F2

Зберегти файл

Save as

Зберегти з ім'ям

Save all

Зберегти усі файли

Change dir

Змінити поточний каталог

Print

Друк

Printter setup

Установка друку

Dos shell

Тимчасовий вихід у DOS

Exit

Alt+X

Вихід із середовища

Розглянемо основні команди.

Команда New відкриває нове редакційне вікно з ім'ям за замовчуванням NONAMExx.PAS, де хх – числа від 00 до 99, і робить його активним. Призначення вікна – створення вихідного тексту нового файлу. При записі ТР запросить ім'я файлу.

Розглянемо структуру вікна (рис. 7.1).

[I]

NONAME00.PAS

1

*

1:1

Елемент закриття вікна

Кнопки вертикальної та горизонтальної прокрутки

Признак зміни тексту

Положення курсору (рядок, стовпець)

Якщо курсором миші зачепити кут чи границю вікна, можна змінити розмір вікна

Якшо курсором миші зачепити ім’я файлу чи подвійну лінію, можна змінити положення вікна

Номер вікна

Рисунок 7.1. Структура вікна середовища програмування ТР

Вікна можна відкривати і закривати, змінювати їхні розміри і переміщувати.

Команда Open відкриває діалогове вікно Open a File:

Якщо в поле введення  ввести *.PAS, то в полі File з'явиться список імен  усіх файлів з розширенням .PAS.

Імена файлів, що останніми викликалися, додаються в список передісторії, куди можна ввійти двома способами: або клацнути по клавіші
   або скористатися мишею.

Передісторія використовується для повторного входження в тексти, у яких уже працювали.

Обране ім'я файлу в списку файлів попадає в поле введення. Введення закінчується натисканням Enter. Для скасування команди - Esc.

В інформаційній панелі відображається шлях обраного файлу, його розмір, дата і час створення.

Функції кнопок:

Open відкриває нове вікно редагування і поміщає в нього текст обраного файлу.

Replace заміняє файл в активному вікні редагування обраним файлом, не відкриваючи нового вікна.

Cancel скасовує всі дії і виводить з діалогового вікна.

Help виводить вікно підказки.

Усередині вікна переключення виконуються кл. Tab.

Команда Save записує файл з активного вікна на диск, якщо файл не мав імені, то відкриється вікно Save File As для перейменування файлу.

Кнопкою Ok підтверджують обрану дію. Функції інших кнопок такі ж, як і кнопок у вікні Open a file.

Команда Save as ...  відкриває вікно в якому можна зберегти файл під іншим ім'ям, в іншому каталозі чи диску. Усі вікна з цим файлом обновлять ім'я.

Команда Change Dir…відкриває вікно Change Directory, у якому задається необхідний поточний каталог. Поточним каталогом є той, котрий використовується ТР для запам'ятовування файлів і їхнього пошуку.

Команда Print друкує текст програми з активного вікна редагування. Для цього  потрібно натиснути Ctrl+K+P.

Команда DOS Shell  застосовується для тимчасового виходу з ТР у середовище DOS. Для повернення в ТР потрібно набрати Exit і натиснути Enter.

Команда Exit завершує роботу в ТР.

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

Щоб пасивне вікно стало активним, потрібно навести на нього курсор мишки і клацнути по лівій кнопці.

Якщо мишки немає, зміна і переміщення вікна виконується в такий спосіб: зробити вікно неактивним (Ctrl+F5), потім стрільцями керування курсором змінюємо положення вікна, а командою Shift + стрілка курсору змінюємо його розмір. Активність вікна відновлюємо кл. Еsс.

Секція Edit. Редагування тексту. Блокові команди. Секції Run і Compile

Секція Edit. Убудований редактор, що має наступні команди (табл. 7.2).

Таблиця 7.2. Команди секції Edit

Команда

Функціональна клавіша

Дія

Undo

Alt+BkSp

Скасувати останню команду

Redo

Скасувати команду Undo

Cut

Shift+Del

Вирізати фрагмент

Copy

Ctrl+Ins

Копіювати фрагмент

Paste

Shift+Ins

Вставити фрагмент

Clear

Ctrl+Del

Очистити вікно

Show clipboapd

Перехід до буфера обміну

Команда Undo скасовує останню команду в рядку. Так, якщо видалити рядок командою Ctrl+Y, то Undo відновить її. Команда працює в останньому вилученому чи зміненому рядку.

Команда Cut вирізає виділений текст і поміщає його на зберігання в Clipboard.

Команда Сору поміщає виділений текст у Clipboard не вирізаючи його на відміну від команди Cut.

Команда Paste вставляє виділений текст із Clipboard у поточне вікно з позиції курсору.

Команда Clear видаляє виділений текст, не поміщаючи його в Clipboard.

Команда Show clipboard відкриває вікно з занесеними в нього на збереження текстами. Тексти у вікні можна редагувати. Виділений командою Shift+ текст, можна скільки завгодно раз витягати з цього вікна і вставляти в новий текст командою Paste.

Редагування тексту. Блокові команди. При створенні тексту і його редагуванні необхідно користатися послугами блокових команд –– це заощаджує час.

Виділення блоку чи слова Sift+

Копіювання блоку Ctrl+K+C

Переміщення блоку Ctrl+K+V

Видалення блоку Ctrl+K+Y

Відновлення вилученого блоку Alt+BkSp

Запис блоку на диск Ctrl+K+W

Читання блоку з диска Ctrl+K+R

Включити/виключити підсвічування блоку Ctrl+K+H

Роздрукувати блок на принтері  Ctrl+K+P  

Зрушити блок вправо  Ctrl+K+I

Зрушити блок уліво  Ctrl+K+U

Команди на клавішах виконуються так: Ctrl+K+C - натиснути Ctrl і, не відпускаючи її, клацнути по клавіші ДО, потім по С.

Команда зрушення блоку виконує його зрушення на одну позицію. Для зрушення блоку на кілька позицій необхідно повторити команду кілька разів.

Вилучений блок (слово) можна відновити, якщо після видалення не виконуються інші команди.

Виділення слова виконується з позиції курсору до кінця слова. Виділене слово - це мінімальний блок і до нього застосовні всі блокові команди.

Виділений блок переміщається чи копіюється в інше місце, починаючи з позиції курсору.

Зайвий символ у тексті усувають кл. Delete, якщо курсор під символом, чи кл. Backspace, якщо курсор праворуч від символу.

Кл. Ins вибирають режим вставки /заміщення символу. У режимі за-міщення курсор має форму миготливого прямокутника.

Праворуч і знизу вікна розташовані смуги скролінга, що дозволяють прокручивать текст у вікні за допомогою мишки. Текст можна переміщати нагору/униз, використовуючи PgUp/PgDn .

Введення кожного нового рядка закінчується натисканням Enter.

Секція містить наступні команди (табл. 7.3).

Таблиця 7.3. Команди секції Run

Команда

Функціональна клавіша

Дія

Run

Ctrl+F9

Виконати

Step over

F8

Пошагово трасувати без заходу в процедури

Trace into

F7

Пошагово трасувати з заходом у процедури

Go to cursor

F4

Виконати до рядка з курсором

Programm reset

Ctrl+F2

Скинути програму

Parametres

Установити параметри

Команда Run запускає програму на виконання в середовищі IDE.

Команда Step over пооператорно виконує поточну процедуру не трасуючи процедури нижчого рівня.

Команда Trace into виконує програму построчно. Процедура при цьому виконується пооператорно, а не в цілому. Команда дає можливість простежити порядкове виконання програми. Для цього потрібно по черзі натискати F7 - для запуску і Alt+F5 - для видалення вікна, щоб бачити результат виконання.

Команда Go to cursor запускає програму на виконання від місця останова до рядка, на якій установлений курсор. Якщо цей рядок не містить виконуваний оператор, то буде видане про це повідомлення.

Команда Program reset зупиняє виконання налагодження, звільняє пам'ять і закриває усі файли, використовувані програмою.

Команда Parameters відкриває діалогове вікно для введення параметрів поточної програми.

Секція  Compile містить наступні команди (табл. 7.4).

Таблиця 7.4. Команди секції Compile.

Команда

Функціональна клавіша

Дія

Compile

Alt+F9

Компіляція

Make

F9

Зборка

Bund

Повна зборка

Destination (memory, disc)

У яку пам'ять компілювати

Primary file

Основний файл

Команда Compile компілює файл в активному вікні і виводить вікно стану з результатами, що відаляються після натискання будь-якої клавіші. При виникненні помилки у вікні виводиться повідомлення.

Команда Make включає убудований Project Manager для створення файлу .ехе.

Команда Destination Memory визначає місце запам'ятовування виконуваного коду - файлу типу .ехе - у пам'яті (Memory), чи на диску (Disk). Вибір установки Memory /Disk виконується кл. Enter.

Команда Primary file використовується при роботі з програмою, що має кілька модулів з розширеннням .tpu чи Include файлів.

Питання для контролю.

1. Як створити новий вихідний текст файлу?

2. Як відкрити вихідний текст існуючого файлу? Призначення передісторії.

Як зберегти вихідний текст файлу?

4. Які функції кнопок Replace, Cancel і Help?

5. Як зберегти вихідний текст файлу під іншим ім'ям?

6. Який каталог називається поточним і як його змінити?

7. Як роздрукувати вихідний текст програми на принтері?

8. Як виконати тимчасовий вихід у DOS і повернутися в ТР?
9. Яка команда записує усі файли у відкритих вікнах?

10. Як виконати переключення усередині вікна?

11. Яка інформація відображається в інформаційній панелі?

12. Яке вікно є активним? Ознаки активного вікна.

13. Ознаки пасивного вікна і як його зробити активним?

14. Як змінити розміри вікна і його положення на екрані?

15. Як закрити вікно і що відбудеться, якщо в ньому був змінений файл?

16. Як перемістити і змінити розміри вікна без допомоги мишки?

  1.  Команди Undo, Cut, Copy, Paste.
  2.  Призначення вікна Clipboard. Як переглянути уміст вікна?
  3.  Чи можна редагувати тексти у вікні Clipboard? Як витягти текст
    із вікна Clipboard?
  4.  Назвіть команди:
  5.  виділення блоку чи слова;
  6.  копіювання і переміщення блоку;
  7.  видалення і відновлення вилученого блоку;
  8.  запису блоку на диск і читання блоку з диска;
  9.  включення/вимикання підсвічування блоку;
  10.  роздруківки блоку на принтері;
  11.  зрушення блоку вправо і вліво.
  12.  Розповісти як виконується редагування (виправлення допущених
    помилок)?
  13.  Розповісти про команди Run, Step over, Trace into і Compile.
  14.  Розповісти про команду Destination Mеmory.


Тема 8: Вираження і пріоритет операцій. Стандартні математичні функції та процедури

В математиці вираженням є формула, що відбиває математичні відносини. У мовах програмування замість “формула” говорять “вираження”. У порівнянні з математичними поняттям  вираження має свої особливості: воно складається з констант, змінних, функцій і операцій над ними.

Вираження визначають порядок виконання операцій. Операції визначають дії, які треба виконати над операндами.

Часто вираженням є константа, перемінна чи функція.

При складанні виражень необхідно дотримуватись наступних правил.

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

 повинна бути записана у виді вираження:

У вираженні неможна застосовувати квадратні і фігурні дужки, тому що вони мають інше призначення. Використовуються тільки круглі дужки. Наприклад, математичне вираження:

варто записати у вигляді

Якщо вираження записане правильно, то кількість дужок, що відкриваються, дорівнює числу закриваючих дужок. Зайві правильно поставлені дужки не впливають на результат.

Неможна записувати підряд два знаки операцій. Наприклад, вираження:

a+b/-c  записано невірно; його варто записати у видгляі

a+b/(-c).

Складні вираження потрібно розбивати на декілька простих, а повторювані дії обчислювати окремо. Наприклад, вираження:

(a+bx)-2(a+bx)+c(a+bx)     варто записати в такий спосіб

x:=a+b*x

z:=y-2*y+c*y

Вираження може бути арифметичним і логічним. При виконанні операції у вираженнях слід дотримуватися пріоритету операцій (табл. 8.1).

Таблиця 8.1. Пріоритет операцій.

Пріоритет

Тип дій

Операції або елементи

1

2

3

4

5

6

Обчислення в круглих дужках

Обчислення значень функції

Унарні операції

Мультимедійні операції

Аддитивні операції

Операції відношень

( )

Функції

@, not, унарні + та -

*, /,div, mod, and, shl, shr

+ , -, or, xor

=, <>, <, >, <=, >=, in

Пріоритет операторів визначаються за наступними правилами:

Операнд, що знаходиться між двома операндами з різними пріоритетами, зв'язується з оператором, що має більш високий пріоритет.

Операнд, що знаходиться між двома операторами з рівними пріоритетами, зв'язується з оператором, що знаходиться ліворуч його.

При наявності дужок спочатку виконується дії в них, при цьому, виконання варто починати з дій у самих внутрішніх дужках.

Операції, зазначені в одному рядку, мають однаковий пріоритет.

Розглянемо приклад. Дано логічне вираження:

(a > 3) and (b = a + 6) or not (c = 4)

Визначити його результат при А = 2, В=8, С=5.

Порядок виконання операцій наступний:

Виконується операція порівняння А>С у перших дужках, її результат False, тому що 2<3;

Виконується дія в других дужках з дотриманням пріоритету – спочатку обчислюється значення А+6, а потім значення В порівнюється зі значенням А+6. Результат – True тому що 8=8;

Виконується операція порівняння С = 4 у третіх дужках, її результат False, тому що 5 не дорівнює 4;

Виконується операція Not (С = 4), її результат  True, тому що Not False є True;

Виконується операція And над першими і другими дужками - False And True, результат її True;

Виконується операція Or над вираженням ліворуч і праворуч від неї - False Or True, результат її True;

Отже, остаточний результат логічного вираження – True.

Приклад. Визначення значень логічних змінних У1, У2, У3.

const

t = true; {логічна константа}

var

b1, b2, b3 : boolean; {логічні змінні}

begin

b1 := false;

b2:=t and b1;

b1 := (not b2) or (not b1);

b3 := b1 and b2 and t;

writeln (‘b1=’,b1,’ ’,’b2=’,b2,’ ‘,’b3=’,b3)

end.

Приклад. Визначити значення логічного вираження

(a>b) and (b=a+2) or not (c<>b)

при наступних даних: А=7, У=9, З=5.

var

l : boolean; {логічна змінна}

a, b, c : integer;

begin

writeln (‘Введіть цілі значення a, b, c :’);

read(a, b, c);

l:=(a>b) and (b=a+2) or not (c<>);

writeln (‘Значення логічного вираження = ‘, l)

end.

Стандартні математичні функції і процедури

Розглянемо основні математичні функції і процедури стандартної бібліотеки System Turbo Pascal.

Функції:

Abs(x) – повертає абсолютне значення х.

Наприклад, abs(-2.4)=2.4;

Cos(x) – повертає косинус числа х (х у радіанах )

Наприклад:

var

x : real;

begin

x := -46.78;

writeln(cos(x));

end.

Sin(x)-повертає синус числа х(х у радіанах).

Arctan(x)-повертає арктангенс числа х.

Exp (х)-повертає число рівне E в ступені х.

Наприклад:

var

x : real;

begin

x:=5.36;

writeln(exp(x));

end.

Ln(x) –повертає число рівне натуральному логарифму від числа х.

Наприклад:

var

x : real;

begin

x := 146.78;

writeln(ln(x));

end.

Pi –число Пі.

Наприклад:

var

r : real;

begin

r := 0.873;{радіус кола}

writeln('площа кола=',2*pi*r*r);

end.

Sqr(x) - зводить число х у квадрат.

Sqrt(x) - витягає корінь квадратний  з числа х.

Наприклад:

var

x : real;

begin

x := 7.78;

writeln('x у квадраті =',sqr(x));

writeln('квадратний корінь з х=',sqrt(x));

end.

Trunc(x) - повертає число, рівне цілій частинй числа х, відкидаючи його дробову частину.

Наприклад:

var

x : real;

begin

x := -7.98;

writeln(trunc(x));

end.

Frac(x) – повертає число, рівне дробової частини числа х, відкидаючи його цілу частину

Наприклад:

var

x : real;

begin

x:=-7.98;

writeln(frac(x));

end.

Int(x) – повертає ціле число, рівне округленій частині числа х, при цьому округлення виконується убік найближчого меншого цілого числа.

Наприклад:

var

a, b, c, d : real;

begin

a := -0.97; b := -2.8; c := 0.97; d := 2.8;

writeln(‘a=’,int(a):3:1,’; b=’,int(b):3:1,’; c=’,int(c):3:1,’; d=’,int(d):3:1);

end.

Результати: a = 0.0; b = -2.0; c = 0.0; d = 2.0

Round(x) - повертає ціле число, рівне округленій частині числа х, при цьому округлення виконується за правилами математики.

Наприклад:

var a, b, c, d : real;

begin

a :=-2.3; b :=-2.5; c :=2.4; d:=2.5;

writeln(‘a=’,round(a),’b=’,round(b),’c=’,round(c),’d=’,round(d))

end.

Результати: a=-2 b=-3 c=2 d=3

Random(x) – генерує випадкові числа від 0 до х. Якщо аргумент х не заданий, то числа генеруються від 0 до 1.

Наприклад:

 var x: integer;

begin

for x:=1 to 10 do

 write(random(x):2,’;’);

end.

  

Результати:0; 0; 2; 0; 1; 4; 2; 1; 3; 4;

 

Odd(x)-повертає True, якщо число х непарне і Flalse - якщо парне.

Наприклад:  

var x:integer;

begin

for x:=1 to 5 do

 write(Odd(x),’;’);

end.

Результати: True; False; True; False; True;

Процедури:

Inc(x,y) - збільшує значення числа х на величину y. Якщо y не зазначений, х буде збільшуватися на 1.

Dec(x,y) - зменшує значення числа х на величину y. Якщо y не зазначений, х буде зменшуватися на 1.

Наприклад:

var n: integer;

begin

n := 5; writeln(‘для n=’,n);

inc(n); writeln(‘inc(n)=’,n);

n:=5;

inc(n,2);writeln(‘inc(n,2)=’,n);

n:=5;

dec(n);writeln(‘dec(n)=’,n);

n:=5;

dec(n,4);writen(‘dec(n,4)=’,n)

end.

Результати: для n=5

inc(n)=6

inc(n,2)=7

dec(n)=4

dec(n,4)=1

Randomize- забезпечує розбіжність послідовностей псевдовипадкових чисел, генеруємих функцією Random.

Наприклад:

var x:integer;

begin

randomize;

 for x:=1 to 10 do

  write(random((x)+1):2,’;’)

end.

Питання для контролю.

  1.  В чому полягає різниця між формулою в математиці і вираженням у Pascal-і?
  2.  Що визначають вираження, а що операції?
  3.  Яких правил потрібно дотримуватися при складанні виражень?
  4.  Яким маже бути вираження? Перелічте пріоритет операцій при виконанні дій у вираженнях.
  5.  Назвіть правила визначення пріорітету операторів у вираженні.
  6.  Назвіть функції що повертають
  7.  абсолютне значення заданого числа і косинус заданого числа;
  8.  синус і арктангенс заданого числа;
  9.  експоненту;
  10.  число, рівне натуральному логарифму від заданого числа;
  11.  число Пі.
  12.  Як звести число Х в квадрат?
  13.  Як витягти квадратний корінь з числа Х?
  14.  Як повернути число, рівне цілій частині заданого числа?
  15.  Як повернути число, рівне дробовій частині заданого числа?
  16.  Як повернути ціле число, рівне округленій цілій частини заданого числа?
  17.  Назвіть функцію, що генерує псевдовипадкові числа.
  18.  Як забезпечити розбіжність генеруємих псевдовипадкових чисел?
  19.  Дано число Х. Що повертає функція Odd(X)?
  20.  Назвіть процедури що збільшують і зменшують задане число Х на величину У.


Тема 9: Умовний оператор. Вкладений умовний оператор

Оператори Pascal. Поняття оператора Pascal.

Розглянемо приклад з математики:

Дану задачу можна записати так:

  1.  якщо х<0, то обчислити 2х+1;
  2.  якщо  х>=0, то обчислити 2х-1;

чи ще коротше:

Якщо х<0, то обчислити 2х+1, інакше обчислити 2х-1.

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

У Pascal-і 12 операторів. Три оператори називаються простими, оскільки не містять інших операторів, інші – структурними, тому що в їхній склад входять інші оператори; структурні оператори задають правила виконання вхідних у їхній склад операторів.

Оператори, що включаються в структурні, також можуть бути структурними і глибина такої вкладеності не обмежена.

У залежності від способу передачі керування оператори поділяються на лінійні і нелінійні.

Лінійні оператори виконуються в порядку  їхнього розташування в програмі.

Таких операторів 5: порожній, складений, присвоєння, процедури/функції, приєднання.

Нелінійні оператори змінюють порядок виконання інших операторів у залежності від деякої умови. Таких операторів 6: переходу, умовний, варіанта, циклу з предумовою, циклу з постумовою, циклу з параметром.

Загальна структура оператора Pascal має вигляд:

[ім'я мітки:][оператор];

Дужки [] означають необов'язкову опцію (частину) оператора. Кожному оператору може передувати мітка, відділена від нього ”:”, і яка служить для позначення місця передачі керування оператором goto. Запис кожного оператора повинен закінчуватися ”;”.

Порожній оператор не містить операційної частини, не виконує дій і позначає  просто ”;”.

Застосовується він у випадку, якщо в деякому місці програми повинний стояти оператор, на який треба послатися, але не виконати ніяких дій.

Наприклад, перехід у кінець складеного оператора:

begin

goto label_1;

label_1: ;

end;

Однак, невірне застосування порожнього оператора може вплинути на результати виконання програми.

Складений оператор являє собою пару ключових слів Begin-End, що містять довільну кількість інших операторів і служить для їхнього об'єднання в один оператор, якщо це потрібно за синтаксом Pascal-я.

Загальна схема складеного оператора:

begin

оператор_1;

оператор_2;

end;

Приклад:

begin {обмін значеннями х та у }

z := x;

x := y;

y := x { ; після останнього оператора можна не ставити}

end;

Оператор присвоювання має загальний вид:

ліва частина := права частина;

Ліва частина - змінна чи ідентифікатор функції, права частина -вираження. Символ оператора := повинний писатися разом, без пробілу.

Правила виконання оператора:

1. Обчислюється вираження правої частини

2. Отриманий результат привласнюється лівій частині.

Тип вираження повинний співпадати з типом лівої частини. Оператор присвоювання допустим для всіх типів, крім файлових.

Приклад для різних типів лівої частини:

x:=(x+y)/(2+z*10)-0.5;

result:=(1>100) or (a[i]=0);

color:=red;

my_set:=[1,7..10,100];

Оператор процедури/функції викликає процедуру чи функцію за їх іменем і передає їм фактичні параметри. Оператор процедури/функції має структуру:

ім'я процедури/функції(список фактичних параметрів);

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

Імена фактичних параметрів можуть не збігатися з оголошеними при описі процедури чи функції; важливі їхній порядок і збіг типу. Якщо деякі чи всі позиції формальних операторів не заповнені, то помилка не виробляється, але туди надходять випадкові значення з відповідними, як правило помилковими, наслідками.

Після завершення процедури керування передається наступному за викликом оператору. Наприклад:

my_procedure(a,b,c,result);

multyply_matrixes(a.b,c);

z:=func_12(x,y);

exit_program;

Безумовний оператор Goto застосовується для зміни порядку виконання операторів програми шляхом передачі керування оператору з зазначеною міткою. Загальна схема оператора:

goto мітка:

Міткою може бути ідентифікатор чи ціле безнаковое число в діапазоні від 0 до 9999.Мітка повинна бути описана в розділі Label.

Приклад.

label 

metka 1, 17;

goto metka 1;

metka1:

a :=b; goto 17;

17:

b:=c;

Правила використання оператора переходу:

1.Перехід на мітку можливий кілька разів.

2.Мітка, зазначена в операторі переходу, повинна  позначати оператор, що знаходиться в тім же блоці, що і сам оператор. Не допускаються переходи з процедур і функцій за їхні межі чи усередину них.

3.Перехід усередину структурного оператора може викликати непередбачені результати, хоча компілятор не дає повідомлення про помилку.

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

У ТР мається чотири безумовних функції: Break, Continue, Exit та Halt.

Призначення їх наступне:

Break - дозволяє достроково закінчити цикл.

Continue - дозволяє почати нову ітерацію циклу, навіть якщо попередня ітерація не була довершена.

Exit - дозволяє завершити роботу програми.

Halt(n)-дозволяє завершити роботу програми з кодом завершення n, де n-ціле число.

Умовний оператор. Вкладений умовний оператор.

Умовний оператор застосовується для вибору до виконання одного з двох можливих операторів в залежності від деякої умови, при цьому один з операторів може бути відсутнім. Умова - це логічне вираження булевського типу. Загальна схема умовного оператора:

If  умова  then оператор_1   [else оператор_2 ];

Якщо умова=True, то виконується оператор_1, якщо False - виконується оператор_2 наступний за “else”(інакше).

Приклад 1.

if x<y then max :=y {; ставити не можна}

else max:=x;

Приклад 2.

if color = red then

begin

end else

begin

end;

Вкладений умовний оператор.Можливе використання вкладених один до одного умовних операторів:

If умова  then if умова then  оператор

еlsе оператор

else оператор

де “else” відноситься до того “if”, що йому передує, тому, для зручності сприйняття програми “еlsе” слід писати під тим “if”, до якого воно відноситься.

Приклад. Написати умовний оператор, що визначає, чи попадає X у діапазон чисел від 5 до 10?

if x>5 then if x<10 then  writelen(‘попадає’)

еlsе writelen(‘x>10’)

еlsе writelen(‘x<5’);

Приклад. Написати умовний оператор обчислення X:

        1,    при a=b, c<d                                             if a=b then

X =   2,    при a=b, c>=d                                           if c<d then x := 1

        3,    при a<>b.                                                              else x := 2

                                                                                              else x := 3;

Варто уникати рівня вкладеності “if” більше 2-х через ускладнення логіки програми.

В умовному операторі можна використовувати складені оператори чи оператори переходу.

if  умова  then

   begin

        оператор_1;

        оператор_2;

         …

        оператор_n

   end else

   begin

         оператор_1;

         оператор_2;

    …

         оператор_n

   end;

перед словом else  “;” не ставлять, тому що else не самостійний оператор, а є складовою частиною оператора if.

Усередині складених операторів можуть бути також умовні оператори. Наприклад:

Обчислити у1=7, y2=A, y3=A+B, якщо A>B; t1=A*B, t2=A-B, якщо A=<B. Фрагмент програми має вид:

if  a>b then

begin

        y1:=7; y2 :=a; y3 :=a+b

end else

begin

t1:=a*b; t2 :=a-b;

       end;

             …

Приклад. З  3-х введених цілих чисел знайти найбільше.

var

     a,b,c: integer;   {цілі числа}

begin

writeln(‘Введіть три цілих числа’);

read(a,b,c);

if (a>b) and (a>c) then

writeln (‘число’, a, ‘найбільше’)

else

if (b>c) then

writeln (‘число’, b, ‘найбільше’)

else

writeln (‘число’, c, ‘найбільше’)

end.

Приклад. При заданому значенні X обчислити Y=1/X.

При складанні програми, варто передбачити перевірку щоб значення X не виявилося рівним 0, тому що на 0 ділити неможна.

var

x,y : real;   {речовинні числа}

begin

writeln(‘Введіть значення x: ’);

read(x);

if x=0 then write(‘На нуль поділяти не можна’)

else

begin

y:=1/x;

writeln (‘y=’, y:1:3);

end;

end.

Приклад. Дан прямокутник і точка з координатами x, y. Визначити, належить вона прямокутнику чи ні? Якщо належить, то повідомити True, якщо ні – False.

var  

x1, x2, y1, y2: real;

x,y : real;

a: boolean;

begin

writeln(‘   x1,y1,x2,y2’);

readln(x1,y1,x2,y2);

writeln(' ');

readln(x,y);

if (x>=x1) and (x<=x2) and (y>=y1) and (y<=y2)  then

a:=true;

else

a:=false;

writeln('  a=',a)

end.

Питання для контролю.

  1.  Що таке оператор?
  2.  Які оператори називаються простими?
  3.  Які оператори називаються структурними?
  4.  В залежності від чого і на які групи поділяються оператори?
  5.  Які оператори називаються лінійними? Перелічте їх.
  6.  Які оператори називаються нелінійними? Перелічте їх.
  7.  Загальна структура Pascal-оператора.
  8.  Порожній оператор. Позначення і застосування.
  9.  Складений оператор. Загальна схема.
  10.  Оператор присвоювання. Загальна форма і правила виконання.
  11.  Для якого типу даних не допустим оператор присвоювання?
  12.  Оператор процедури/функції. Структура. Чим відрізняється виклик функції від виклику процедури?
  13.  Безумовний оператор і правила його застосування.
  14.  Перелічите безумовні функції.
  15.  Умовний оператор і його застосування.
  16.  Який тип умови в умовному операторі?
  17.  Робота умовного оператора.
  18.  4.Вкладений умовний оператор і його робота (до якого “if” відноситься “else”?).
  19.  Використання складених операторів в умовному операторі.
  20.  Чому перед “else” не ставиться “;”?
  21.  Чому не бажаний рівень вкладеності “if” більш 2?


Тема 10: Оператор вибору

Оператор вибору є узагальненням умовного оператора і застосовується у випадках, коли в заданому списку варіантів рішень потрібно вибрати варіант у відповідності зі значенням деякого вираження чи змінної.

Загальний вид оператора:

case вираження чи ім'я перемінної  of

константа_1, константа_2, … :оператор_1;

константа_3, константа_4, … :оператор_2;

[else оператор_3;

оператор_4;

         …             ]

end;

де Case (у випадку), Of (з), Else (інакше) і End - службові слова. В якості оператора може бути і складений оператор.

Кожна гілка, розділена “:”, називається альтернативою. У лівій частині альтернативи стоїть одна чи кілька констант, розділених “,” чи діапазони значень, у правій частині – відповідний їм оператор.

Робота оператора вибору. Спочатку обчислюється значення вираження чи змінної і, у випадку, якщо воно дорівнює одній з констант чи попадає в заданий діапазон значень, то виконується відповідний їй оператор. Потім керування передається за межі оператора вибору. Якщо значення вираження чи змінної не збігається з жодною константою чи не попадає в заданий діапазон значень, то виконується оператор (оператори) після “else” (якщо він є) і керування передається за межі оператора вибору. Якщо “else” немає, то керування передається на оператор End.    

Приклад.

case x+1 of

2..10: y :=sqrt(x);

3,11,y :=a+b*x;

else writeln('значення не збіглися');

end;

Приклад використання списку констант.

case s of

‘+’, ‘-’, ‘*’, ‘\’, ‘=’ : y :=a+b;

‘a’, ‘b’, ‘c’, : y :=a-b;

'у' : y :=0;

end;

Приклад. Ввести номер дня тижня й одержати відповідний йому день українською мовою.

var n : integer {номер дня тижня}

begin

writeln('Введіть номер дня тижня:');

read(n);

case n of 

1: writeln('Понеділок');

2: writeln('Вівторок');

3: writeln('Середа');

4: writeln('Четвер');

5: writeln('П'ятниця');

6: writeln('Субота');

7: writeln('Неділя');

else writeln('Немає такого номеру дня')

end;

end.       

Питання для контролю.

1.Загальний вид оператора вибору і його застосування.

2.Гілка-альтернатива в операторі вибору і її склад.

3.Робота оператора вибору.


Тема 11: Оператори циклу. Оператор циклу з параметром

У Pascal-і мається три види операторів циклу: While – оператор циклу з попередньою умовою, Repeat – оператор циклу з наступною умовою і For – оператор циклу з параметром.

Оператори тіла циклу записуються один раз. Вхід у цикл можливий тільки через його початок. Вихід з циклу повинний виконуватися по його закінченню чи зо оператором переходу. Якщо цього не передбачено, то циклічні дії будуть продовжуватися нескінченно й у цьому випадку говорять, що “програма зациклилася”.

Оператор циклу з параметром застосовується, коли відоме число повторень циклу. Загальний вид оператора:

for i:=n1 to n2 do

begin

оператори тіла циклу

end;

де For, To, Do  – службові слова; і – змінна циклу, n1,n2 – початкове і кінцеве значення перемінної.

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

Змінна циклу і повинна бути простого дискретного типу(найчастіше цілого типу). Крок її зміни дорівнює +1 чи –1. Якщо значення змінної збільшується від n1 до n2, то крок її зміни дорівнює +1, а  якщо зменшується – то її крок зміни дорівнює –1 і  тоді в операторі циклу For замість слова To записують слово Downto.

Початкове і кінцеве значення повинні бути сумісні за типом зі змінною циклу. Тип Real не допустим. Неможна змінювати змінну циклу в тілі циклу – це приведе до перекручування результату.

Приклад. Крок зміни змінної i +1

var

    i,a,s:integer;

begin

    for i:=1 to 4 do

        begin

           a:=a+i;

           s:=2*a;

           writeln(a:3,s:3);

         end;

  end.

Приклад 2. Крок зміни змінної i -1

var

   i,a,s:integer;

begin

    for i:=4 downto 1 do

        begin

           a:=a+i;

           s:=2*a;

           writeln(a:3,s:3);

         end;

  end.

Приклад. Обчислити y=x2 при x=2,4,6,8,10.

var x,k,y: integer;

begin

   x:=2;

   for k:=5 downto 1 do

       begin

          y:=x*x;

          writeln(x:3,y:5);

          x:=x+2;

       end;

 end.

Тут змінна k – лічильник кількості виконуваних обчислень.

Якщо тіло циклу складається з одного оператора, то операторні дужки Begin...End можна не вказувати. У цьому випадку оператор циклу з параметром буде мати вид:

for i:=n1 to n2 do оператор;

Приклад1.      Приклад2.

var  

  i,a,s:integer:

begin

    for i:=1 to 4 do

       begin

           a:=a+i;

           s:=2*a;

           writeln(a:3,s:3);

        end;

end.

var  

  i,a,s:integer:

begin

   for i:=4 downto 1 do

         a:=a+i;

         s:=2*a;

         writeln(a:3,s:3);

   end.

У першому прикладі  оператори тіла циклу взяті в операторні дужки Begin…End в результаті чого цикл For буде виконаний для всіх операторів циклу. Цикл виконується 4 рази і для кожного виконання будуть виведені значення a,s.

У другому прикладі  оператори тіла циклу не взяті в операторні дужки в результаті чого цикл For виконується тільки для оператора a:=a+і, а потім виконується оператор s:=2*a. Будуть виведені останні значення a,s.

Приклад. Вивести на екран латинський алфавіт. Оскільки символи латинського алфавіту упорядковані, програма буде наступною:

var  simbol:char;

begin

writeln(‘Латинський алфавіт:’);

for simbol:=’A’ to ‘Z’ do

write(simbol);

end.

Приклад. Обчислити y=2x+t при x=1.5;2;2.5;3 і t=1;2;3.

Для рішення організуємо два цикли: для змінної х зовнішній цикл While, (значення змінної змінюється на 0,5 і цикл For застосувати неможна), для перемінної t внутрішній цикл For, тому що значення перемінної міняється на 1.

var t: integer;

x,y: real;

begin

x:=1.5;

while x=3 do begin

for t:=1 to 3 do begin

y:=2*x+t;

  writeln(‘y=’,:1:1,’при x=’,x:3:1,’і t=’,t);

 end;

x:=x+0.5;

end;

end.

Питання для контролю.

1. Оператор циклу з параметром і його застосування.

2. Робота оператора циклу з параметром.

3. Змінна циклу, її тип і крок зміни.

4. Який тип неприпустимий для змінної циклу?

5. Застосування в циклі з параметром слів To і Downto.

6. Чи можна змінювати змінну циклу в тілі циклу оператора For?

7. В якому випадку в операторі For можна не ставити операторні дужки?


Тема 12: Оператор циклу з перед- і з постумовою

Оператор циклу з передумовою має загальний вид:

while логічне вираження do

begin

оператори тіла циклу

end;

де While (доки) і Do (виконувати) службові слова.

Робота оператора. Спочатку обчислюється логічне вираження і, якщо воно приймає значення True, то виконуються оператори тіла циклу, а якщо False , то керування передається на оператор після End.

Значення логічного вираження перевіряється перед кожним виконанням операторів тіла циклу.

Оператори тіла циклу, укладені в операторные дужки, являють собою складений оператор.

При використанні в циклічній частині оператора переходу Goto, що передає керування за межі циклу, можна перервати виконання циклу до його природного завершення.

Якщо в циклічній частині знаходиться лише один оператор, то операторні дужки Begin ... End можна опускати. Оператор циклу прийме вигляд:

while логічне вираження do оператор;

Іноді виникає ситуація, коли логічне вираження правдиве чи неправдиве при будь-яких вхідних у нього параметрах. Таке явище називається тавтологією. При тавтології True оператор зациклиться, при тавтології False – ніколи не виконається. Щоб таке не трапилося, параметри логічного вираження повинні змінюватися в тілі циклу.

Приклад, у якому логічне вираження завжди щире, тобто маємо тавтологію True, при якій оператор зациклиться:

var x: real;

begin

x :=0;

while x<>2 do

begin

writeln (x:6:2);

x:=x+0.3

end

end.

Тавтологія тут виникла через помилку в логічному вираженні: замість x<>2 потрібно було написати x<=2.

Приклад. Обчислити y=x2 при x=2, 4, 6, 8, 10.

var x,y: integer;

begin

x:=2;

while x<=10 do

begin

y:=x*x;

writeln(x:3,y:5);

x:=x+2;

end;

end.

При введенні даних в операторі циклу можна використовувати стандартну функцію EoLn. Вона має значення False поки не натиснута кл.Enter.

Наприклад:

var  a,n:integer;

begin

n:=0;

writeln(‘кл.Enter не натиснута і знач. Функції EoLn=’,eoln);

while not eoln  do {поки немає кінця рядка, виконувати цикл)

begin

read(a);

n:=n+a;

end;

writeln(‘n=’,n);

writeln(‘кл.Enter натиснута і значення функції EoLn=’,eoln);

end.

У цьому прикладі тіло циклу буде виконуватися доти, поки не буде натиснута кл. Enter, тобто поки при читанні даних не зустрінеться символ кінця рядка. При цьому функція EoLn  прийме значення True і цикл припиниться.

Приклад. Підрахувати у введеному рядку кількість символів. Ознакою кінця рядка вважати натискання кл.Enter.

var

simbol: char;{символ введеного рядка}

n: integer;

begin

writeln(‘Введіть довільний рядок:’);

while not eoln do {поки немає кінця рядка, виконувати цикл}

begin

read(simbol);

n:=n+1;

end;

writeln;

writeln(‘У введеному рядку усього’,n’,символів’);

end.

Оператор циклу з постумовою має вид:

repeat

оператори тіла циклу

until логічне вираження;

де Repeat(повторити) і Until(доти) службові слова.         

Робота оператора. Спочатку виконуються оператори циклічної частини, а потім перевіряється умова виходу з циклу. Якщо значення логічного вираження False, то виконання циклу повториться. Вихід з циклу здійснюється при правдивому значенні логічного вираження. У зв'язку з тим, що умова перевіряється після виконання циклічної частини, оператори циклу з постумовою завжди виконуються хоча б один раз. Цим оператор циклу з постумовою відрізняється від оператора циклу з передумовою.

Нижня границя операторів тіла циклу чітко позначена словом Until, тому циклічну частину не укладають в операторні дужки Begin...End, але якщо  їх і поставити – помилки не буде.   

При використанні в циклічній частині оператора переходу Goto, що передає керування за межі циклу, можна перервати виконання циклу до його природного завершення.

Приклад 1.Обчислити y=x^2 при x=0,2,4,6,8,10.

var  x,y:integer;

begin

  repeat

      y:=x*x;

      writeln(‘x=’,x,’y=’:5,y);

      x:=x+2

  until x>10

end.

Приклад 2.Обчислити y=x^2 при x=2,2.5,3,3.5.

var x,y:real;

begin

     x:=2;

repeat

          y:=x*x;

  writeln(‘x=’,x:1:1,’y=’:3,y:2:3);

    x:=x+0.5

until x>3.5

end.


Після Repeat і перед Until “;” можна не ставити, тому що ці слова є й операторними дужками. Але, якщо “;” і поставити, те це не буде помилкою.

В прикладі 1 перше значення аргументу x=0 не задано, тому що нульове значення привласнюється автоматично.

Питання для контролю.

1. Які оператори циклу маються в Pascal-і?

2. Як відбувається вхід у цикл і вихід з циклу?

3. Оператор циклу з передумовою. Робота оператора.

4. Як можна перервати виконання циклу до його природного завершення?

5. Явище тавтології і її попередження.

6. Використання функції Eoln при введенні даних.

7. Оператор циклу з постумовою. Робота оператора.

8. Чому циклічну частину в операторі циклу з постумовою не потрібно укладати в операторні дужки?

9. У чому полягає відмінність оператора з постумовою від оператора циклу з передмовою?

10. Чи можна ставити “;” після Repeat і перед  Until?


Тема 13: Складні типи. Масиви 

Нестандартні типи. Тип, що перелічується. Обмежений (интервальный) тип.

Тип, що перелічується, складається зі списку констант. Змінні цього типу можуть приймати значення кожної з цих констант. Опис типу, що перелічується, має вид:

type ім'я типу = (список констант);

var ім'я змінної : ім'я типу;

Список констант являє собою перелік констант, розділених комами. Константи задає користувач, а сам список полягає в круглі дужки. Наприклад:

type

 num = (one, twо, three, four, five);

var

 n1 : num;

Тут num ім'я типу, що перелічується; (one, twо, three, four, five) – список констант; one – значення першої константи, two – другий і т.д.; n1 – змінна, котра може приймати значення будь-якої константи.

Кожна з констант, що перелічуються, у списку має свій порядковий номер. Перша константа має номер 0, друга – 1, і т.д., тобто константи в списку упорядковані, що дозволяє застосувати до них операції відносини <, <=, =, <>, >=, >. Результат операцій логічного типу – True чи False.

Якщо в програмному блоці описується кілька перечислювальних типів, то константи в їхніх списках не повинні повторюватися.

У Раsсаl-і неможна вводити і виводити дані типу, що перелічується, за допомогою операторів Read і Write.

До змінних і констант типу, що перелічується, можна застосовувати стандартні функції Ord, Pred, Succ.

Застосовуючи функцію Ord до значення типу, що перелічується, одержимо його порядковий номер у списку. Приклад.

type

 num = (one, twо, three, four, five);

var

n1, n2: num;

pn1, pn2: integer;

begin

 n1:= two;

n2:= succ(four);

pn1:= ord(n1)+1;

pn2:= ord(n2)+1;

writeln(‘порядковий номер two=’,pn1);

writeln(‘порядковий номер числа після four=’,pn2);

end.

У Pascal допускається вказувати константи типу, що перелічується, у розділі Var без використання роздягнула Type. Так, у попередньому прикладі можна було записати:

var

n1, n2: (one, twо, three, four, five);

pn1, pn2: integer;

begin

. . .

однак, це поганий стиль програмування.

Обмежений (інтервальний) тип. При описі обмеженого типу вказують дві константи початкового і кінцевого значення діапазону для даної змінної, розділені двома крапками. Значення першої константи завжди повинне бути менше значення другої.

Опис обмеженого типу має вид:

type ім'я типу = константа1.. константа2;

var ім'я перемінної: ім'я типу;

Обидві константи повинні належати одному зі стандартних типів. Тип Real – не допустим.

Приклад 1:

Const

 Min = 1;

 Max = 100;

Type

Tempersture = min .. max;

Var

 Temp: temperature;

 . . .

Приклад 2:

Type

 x1 = 1 .. 10;

x2 = -100 .. 100;

x3 = ‘a’ .. ‘z’;

var

 n1 : x1;

 n2 : x2;

 n3 : x3;

. . .

Якщо константи стандартного типу, то опис обмеженості типу (але не обмеженого типу) можна здійснювати безпосередньо в розділі Var, наприклад:

var temp : 1 .. 100;

Тип констант називається базовим. Над змінними обмеженого типу можна виконувати всі операції даних його базового типу.

Застосування обмеженого типу робить програми більш приємними і наочними. Наприклад, якщо в програмі змінна n приймає тільки цілі значення 2, 3, 4, 5, 6, 7, 8, 9 то краще дати опис

var n : 2 .. 9;
ніж

var n : integer;

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

Складні типи. Масиви.

Часто приходиться обробляти велику кількість даних одного типу. При цьому вводять одне узагальнююче ім'я, а індексом відзначають конкретне дане. Наприклад, дана сукупність дійсних чисел

1.5, 0.8, -6.34, 7.21, 0.43


Якщо її назвати ім'ям А, а конкретне число відзначити індексом:

А1, А2, А3, А4, А5,


то одержимо сукупність чисел, що у математиці та інформатиці називається масивом  даних чи вектором.

Масив – це кінцева сукупність даних одного типу, упорядкованих за значеннями індексу. У Pascal кожен елемент масиву позначається ім'ям масиву з індексом, укладеним у квадратні дужки. Так, у приведеному прикладі елементами масиву А є

А[1]=1.5, А[2]=0.8, А[3]=-6.34, А[4]=7.21, А[5]=0.43.

У програмі масив описується або в розділі Var, або в розділі Type. Опис у розділі Var має вид

var ім'я масиву : array[t1] of t2;


де Array (масив) і Of (з) – службові слова; t1 - тип індексу. В якості типу може бути будь-як простий тип, крім Real і Integer; t2 - тип елементів масиву, що називається базовим типом. В якості базового типу може бути простий чи складний тип.

Для приведеного приклада опис масиву має вид

var a : array[1..5] of real;


де А – ім'я масиву, елементи якого мають базовий тип Real. Тип індексу обмежений від 1 до 5.

За причини того, що тип індексу не може бути типу Real чи Integer, опис масиву

var a : array[5] of real;


чи

var a : array[integer] of real;


є помилковим.

Нумерація індексу не обов'язково повинна починатися з 1 чи бути позитивним числом. Наприклад, опис у програмі, що обробляє чисельність населення міста з 1991 по 1996 рік:

var people : array[1991..1996] of integer;


чи з 875 по 1 р. до нашої ери:

 

var people : array[-875..-1] of integer;

Значеннями індексів можуть бути не тільки числа. Наприклад, опис масиву частоти появи латинських букв:

var chastota_symbol : array[‘A’..’Z’] of integer;


чи середньорічної температури в містах

type city = (Kiev, Zaporojie, Dnepropetrovsk, Alusta, Doneck);

var temperatura : array[city] of real;

Якщо кілька масивів мають однаковий тип індексів і однаковий базовий тип, то в їх опис можна об'єднати в один список. Наприклад. Три масиви A, B, C дійсних чисел, кожний з який містить по 20 елементів:

A[1], A[2], … A[20];

B[1], B[2], … B[20];

C[1], C[2], … C[20];


в описі можна об'єднати в список:

var a,  b, c : array[1..20] of real;

В якості індексу може бути вираження (константа і змінна – це окремий випадок вираження). Елемент масиву звичайно називають змінною з індексом.

В операторах присвоювання елементи масиву можуть стояти як у лівій частині, так і в правій частині й у вираженнях:

A[5] := A[3]+2; Sum := Sum + B[2]; Result := A[2*1+2];

Над елементами масиву можна робити ті операції, що припустимі для даних його базового типу.

Для введення і виведення чисельних значень масиву використовують цикли. Наприклад цикл

for i :=1 to 5 do

read(a[i]);


організує введення 5 значень елементів масиву А, а цикл

for i :=1 to 5 do

 writeln(a[i]);


організує уведення висновок 5 значень елементів того ж масиву.

Приклад. Обчислити суму 20 цілих чисел.

Рішення. Для позначення чисел ведемо ім'я масиву М, елементи якого мають індекс і. Суму позначимо ім'ям Sum. Тоді

Sum = M[1]+M[2]+…+M[20];

Програма має вид:

var m : array[1...20…20] of integer;

i:1…20;{можна i : integer}

sum : integer;

begin

for i := 1 to 20 do begin

read(m[ i ]);

sum :=sum+m[ i ];

end;

writeln(`сума = `,sum)

end.

Тут змінна  “i” з одного боку використовується як змінна циклу, а з іншого боку  - як індекс. В розділі Var змінну “i” можна вказати обмеженого типу

 

var m : array[1…20] of integer;

i : 1…20;

чи, зважаючи на те, що елементами обмеженого типу є цілі числа, змінну можна описати як Integer

var m : array[1...20…20]ofinteger;

i:integer;

Опис масивів у розділі Type складається з двох етапів: спочатку в розділі Type указується тип масиву, а потім у розділі Var перелічуються масиви, що відносяться до зазначеного типу.

type ім'я типу = array[ t1 ] of t2;

var ім'я масиву : ім'я типу;

де t1 – тип індексу; t2 – базовий тип елементів масиву.

Приклад. Скласти програму, що визначає ріст найвищого гравця баскетбольної команди.

Програма має вид.

const n=10; {кількість гравців}

type massiv = array[1…n] of integer;

var

sportsman : massiv;

max, i : integer;

begin

{Введення значень росту десяти спортсменів}

writeln(`уведіть ріст 10 спортсменів у див.:`)

for i := 1 to n do

read (sportsman[ і ]);

{визначення найвищого спортсмена}

max :=sportsman [1]);

for i:= 2 to n do 

if sportsman[1] >max then max := sportsman[i];

writeln(`ріст найвищого спортсмена = `,max);

writeln

end.

Питання для контролю.

1. Тип, що перелічується, і його опис.

2. Операції, застосовувані до констант типу, що перелічується.

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

4. Функції, застосовувані до констант типу, що перелічується.

5. Чи можна застосовувати процедури Read і Write для організації введення і виведення даних типу, що перелічується?

6. Чи можна описувати константи типу, що перелічується, у розділі Var без використання роздягнула Type?

7. Обмежений (інтервальний) тип і його опис.

8. Який тип констант інтервального типу неприпустимий?

9. Які операції можна виконувати над змінними інтервального типу?

10. Коли і з якою метою застосовують інтервальний тип у програмах?

11. Визначення масиву даних. Як у Pascal-і позначається елемент масиву?

12.Опис масиву.

13.Якого типу може бути базовий тип масиву?

14.Якою може бути нумерація індексів елементів масиву?

15.Що може бути в якості індексу елементів масиву?

16.В якому випадку кілька масивів при написанні поєднують в один список?

17.Застосування оператора присвоювання при обробці елементів масиву.

18.Які операції можна робити над елементами масиву?

19.Організація введення і виведення значень елементів масиву.


Тема 14: Багатомірні масиви

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

                                                               

A(3,4) =

Дана матриця має розмір 3 на 4, тобто вона складається з трьох рядків і чотирьох стовпців. Матриця позначається ім'ям, а кожен її елемент має два індекси, наприклад, А[i,j], де перший індекс “i” позначає номер рядка, а другий індекс “j” – номер стовпця. Опис матриці має вид.

type massiv = array[1..3] of array[1..4] of integer;

var a:massiv;

або

type massiv = array[1..3,1..4] of integer;

var a:massiv;

де в першому варіанті спочатку описується один тип індексу 1..3, потім указується складний базовий тип Array[1..4] Of  Integer, що у свою чергу містить опис другого типу індексу і простого базового типу Integer. В другому випадку описується кожен тип індексу, потім указується простий базовий тип елементів масиву Integer.

Якщо в програмі потрібно виділити окремі рядки матриці, опис буде мати вид

type

massiv1= array[1..4] of integer;

massiv = array[1..3] of massiv1;

var

a : massiv;  b : massiv1;

тут спочатку описується тип одного рядка Massiv1, а потім, через тип рядка Massiv1 описується тип усієї матриці Massiv; у розділі Var “A” є двовимірним масивом, а “B” – одномірним масивом.

Типи індексів матриці можуть бути різними, що дозволяє описувати дані в більш природному виді. Наприклад, опис шахівниці, де поля позначаються як цифрами, так і буквами, може бути таким:

type bukva = ( a, b, c, d, e, f, g, h, );

type doska = array[bukva, 1…8] of figural;

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

writeln(`Введення елементів матриці:`);

for i := 1 to n do

for j :=1 to m do

read(a[ i, j ]);

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

writeln(`Виведення елементів матриці:`);

for i :=1 to n do

begin

for j :=1 to m do

write(a[ i, j ]);

writeln;{ця процедура потрібна для порядкового виведення матриці}

end;

Приклад. Дано матрицю дійсних чисел А.

         А(3,5)=

                                                                           

Одержати матрицю В, значення якої дорівнюють подвоєним значенням матриці А.

const n=3;{кількість рядків}

m=5;{кількість стовпців}

type  massiv = array[1..n,1..n] of real;

var

a,b : massiv;{масиви типу massiv}

i : integer; {індекс рядка}

j : ineger; {індекс стовпця}

begin

writeln(`введіть значення матриці А :`);

for i := 1 to n do

for j := 1 to m do

read(a[i,j]);

{обчислення значень матриці В:`);

for i := 1 to n do

for j :=1 to m do

b[i,j]:=a[i,j]*2;

writeln(‘виведення значень матриці В :’);

 for i:=1 to n do

 begin

  for j:=1 to m do

write (b[ i, j ]:3:1,’ ’:2 );

writeln;

end;

end.

Питання для контролю.

1.Багатомірний масив і його опис.

2.Позначення елементів матриці.

3.Якими можуть бути типи індексів матриці?

4.Організація введення елементів матриці.

5.Організація виведення елементів матриці.


Тема 15: Пошук і сортування елементів масиву. Класи алгоритмів сортування 

Сортування методом вибору найменшого елемента

Пошук мінімального (максимального) елемента в масиві

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

Алгоритм пошуку розглянемо на прикладі. Нехай заданий масив різних елементів:

x1 , x2 , x3 … xn ;

Необхідно знайти мінімальне значення елементів масиву і номер мінімального елемента.

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

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

{Пошук миним. елемента в масиві і його номер}

const n=10;

type massiv=array[1..n] of real;

var

x : massiv; i, nom : integer; min : real;

begin

writeln(‘введіть’,n,’елементів масиву:’);

for i :=  1 to n do read(x[ i ]);

min := x[1]; nom :=1;

for i := 2 to n do

begin

if min > x[ i ] then

begin

min := x[ i ]; nom :=i

end

end;

writeln(‘мінімальне значення’,min:2:3);

writeln(‘це’,nom’элемент масиву.’)

end.

Сортування методом вибору найменшого елемента

Задача сортування полягає в перестановці елементів масиву у визначеному порядку, наприклад, у порядку убування чи зростання.

Наприклад.

Вихідний масив                                                        

Упорядкований за                                           

зростанням масив                                                     

 

Розглянемо три найбільш прості методи сортування.

Сортування методом вибору найменшого елемента полягає в наступному. Знайдемо в масиві елемент із найменшим значенням і поміняємо його місцями з першим елементом. Потім розглянемо масив, що залишився, без першого елемента, починаючи з 2-го, і повторимо ті ж дії. Так продовжуємо доти, поки не залишиться один, останній елемент. Він буде найбільшим. У результаті одержимо масив упорядкований по зростанню значень елементів. Приклад програми:

const

n=10;

type massiv=array[1..n] of real;

var

a : massiv; i, j, k : integer; x : real;

begin

writeln(‘введіть’,n,’елементів масиву:’)ж

for i :=1 to n do read(a[ i ]);

writeln(‘упорядкований по зростанню масив:’);

for i :=1 to n do

begin 

k :=i; x := a[ i ];

for j :=i+1 to n do

if a[ j ] < x then

begin

x :=a[j];

k :=j;

end;

a[ k ] :=a[ i ];

a[ i ] :=x;

write(x:6:2);

end;

end.


Сортування методом обміну (метод “пухирця”)

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

Значення елементів масиву необхідно упорядкувати по зростанню.

Розглянемо його від кінця до початку (порядок розгляду не має значення). Порівняємо 4-й і 5-й елементи. Вони розташовані не в порядку зростання, поміняємо їх місцями. Положення елементів буде наступним:

Тепер порівняємо 3-й і4-й елементи. Вони розташовані в порядку зростання і їх залишимо на місці. Порівнюємо 2-й і 3-й елементи і змінюємо їх місцями:

І, нарешті, порівнюємо і змінюємо місцями 1-й і 2-й елемент

21  72  203  34   155

У результаті мінімальний елемент перемістився на перше місце в масиві. Розглянутий процес повторюємо доти, поки елементи масиву не виявляться упорядкованими по зростанню їхніх значень. Перестановка елементів у попарному порівнянні нагадує всплиття пухирця повітря в рідині, відкіля і названий даний метод сортування.

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

const

   n=10;

type massiv=array[1..n] of integer;

var

a : massiv; i, j, x : integer;

begin

writeln('Введіть 10 значень елементів масиву:');

for i := 1 to n do read (a[i]);

writeln(‘упорядкований по зростанню масив:’);

for i := 2 to n do

begin

for j := n downto i do

if a[j-1] > a[j] then

begin

x := a[j-1];

a[j-1] := a[j];

a[j] := x;

end;

for := 1 to n do

write(a[i],’’);

end;

end.


Сортування методом уставок

Полягає в наступному. Нехай у заданій послідовності А[1], А[2], ..., А[n] перші елементи уже відсортовані. У цій частині послідовності будемо шукати місце для і-го елемента, порівнюючи його один по одному зі всіма елементами, що знаходяться ліворуч, поки не виявиться, що деякий А[j] елемент<=A[і]. Зрушимо праву частину послідовності A[j+1], A[j+2], ..., A[j-1] на один елемент у право, звільнивши місце A[j=1] для елемента A[і], куди його і поставимо.

У випадку, якщо виявиться, що елемент A[і] менше всіх елементів, що стоять ліворуч, і місце йому не знайдено, перегляд закінчимо по досягненню першого елемента і всю послідовність зрушимо на один елемент вправо, а елемент A[і] поставимо на перше місце.

Проробивши подібні дії від 2-го елемента до n-го, одержимо упорядковану по зростанню значень елементів послідовність.

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

const

n=10;

type massiv=array[1..n] of integer;

var

a : massiv;

i, j, x : integer;

begin

writeln('введіть вектор з ',n,' цілих чисел:');

for і := 1 to n do

          read(a[i]);

writeln(‘упорядкований по зростанню вектор:’);

for i := 2 to n do

begin

x := a[i];

j := i-1;

while (x<a[j]) and (j>0) do

begin

a[j+1] := a[j];

j := j-1;

end;

a[j+1] :=x;

for i:= 1 to n do

write(a[i],’’);  

end.

Питання для контролю.

1. Задача пошуку елемента в масиві і задача сортування елементів у масиві.

2. Алгоритм пошуку мінімального елемента в масиві і визначення його номера.

3. Алгоритм сортування методом вибору найменшого елемента.

4. Алгоритм сортування методом уставок. Приклад програми.


Тема 16: Динамічна пам'ять. Адреси і покажчики

Динамічна пам'ять

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

Динамічна пам'ять - це оперативна пам'ять ПК, що надається програмі при її роботі, за вирахуванням сегменту даних (64 Кбайт), стека (звичайні 16 Кбайт) і власне тіла програми. Розмір динамічної пам'яті можна варіювати в широких межах (див. пріл.1). За умовчанням цей розмір визначається всією доступней пам'яттю ПК і, як правило, складає не менше 200...300 Кбайт.

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

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

Адреси і покажчики    

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

Турбо Паскаль надає в розпорядження програміста гнучкий засіб управління динамічною пам'яттю - так звані покажчики.

Покажчик - це змінна, яка як своє значення містить адресу байта пам'яті.

У ПК адреси задаються сукупністю два шестнадцатіразрядних слів, які називаються сегментом і зсувом. Сегмент - це ділянка пам'яті, що має довжину 65536 байт (64 Кбайт) і що починається з фізичної адреси, кратної 16 (тобто Про, 16, 32, 48 і так далі). Зсув вказує, скільки байт від початку сегменту необхідно пропустити, щоб звернутися до потрібної адреси.

Адресний простір ПК складає 1 Мбайт (йдеться про так званій стандартній пам'яті ПК; на сучасних комп'ютерах з процесорами 80386 і вище адресний простір складає 4 Гбайт, проте в Турбо Паськале немає засобів, що підтримують роботу з додатковою пам'яттю; при використанні середовища Borland Pascal with Objects 7.0 така можливість є). Для адресації в межах 1 Мбайта потрібне 20 двійкових розрядів, які виходять з двох шестнадцатіразрядних слів (сегменту і зсуву) таким чином (рис. 16.1): вміст сегменту зміщується вліво на 4 розряди, праві розряди, що звільнилися, заповнюються нулями, результат складається з вмістом зсуву.    

Рисунок 16.1. Схема формування адреси в ПК  

Фрагмент пам'яті в 16 байт називається параграфом, тому можна сказати, що сегмент адресує пам'ять з точністю до параграфа, а зсув - з точністю до байта. Кожному сегменту відповідає безперервна область пам'яті, що окремо адресується. Сегменти можуть слідувати в пам'яті один за іншим без проміжків або з деяким інтервалом, або, нарешті, перекривати один одного.  

Таким чином, по своїй внутрішній структурі будь-яким покажчиком є сукупність двох слів (даних типа WORD), що трактували як сегмент і зсув. За допомогою покажчиків можна розміщувати в динамічній пам'яті будь-якій з відомих в Турбо Паскалі типів даних. Лише деякі з них (BYTE, CHAR, SHORTINT, BOOLEAN) займають у внутрішній виставі один байт, останні - декілька суміжних. Тому насправді покажчик адресує лише перший байт даних.

Питання для контролю.

1. Дати визначення динамічної пам’ятті.

2. В чому полягає різниця при обробці данних в динамічній та статичній пам’ятті?

3. Дати визначення покажчика.

4. Як формується адреса в ПК?

5. Скільки місця в пам’ятті займає покажчик?


Тема 17: Оголошення покажчиків, виділення та звільнення динамічної пам’яті

Оголошення покажчиків    

Як правило, в Турбо Паскалі покажчик зв'язується з деяким типом даних. Такі покажчики називатимемо такими, що типізуються. Для оголошення покажчика, що типізується, використовується значок ^, який поміщається перед відповідним типом, наприклад:  

var  

P1 :^Integer;    

р2 :^Real;    

type  

Perconpointer = Perconrecord;    

Perconrecord = record  

Name : String;  

Job : String;  

Next : Perconpointer;

end;   

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

Рисунок 17.1. Облікова структура даних  

У Турбо Паскалі можна оголошувати покажчик і не зв'язувати його при цьому з яким-небудь конкретним типом даних. Для цього служить стандартний тип POINTER, наприклад:  

var  р: pointer;  

Покажчики такого роду називатимемо такими, що не типізуються. Оскільки покажчики, що не типізуються, не пов'язані з конкретним типом, з їх допомогою зручно динамічно розміщувати дані, структура і тип яких міняються в ході роботи програми.  

Як вже говорилося, значеннями покажчиків є адреси змінних в пам'яті, тому слід було б чекати, що значення одного покажчика можна передавати іншому. Насправді це не зовсім так. У Турбо Паськале можна передавати значення лише між покажчиками, пов'язаними з одним і тим же типом даних. Якщо, наприклад,  

var  

p1,p2: integer;    

р3 : Rеа1;    

рр : : pointer;

то привласнення  p1 := р2;  сповна допустимо,

тоді як  р1 := р3;  

заборонено, оскільки р1 і р3 вказують на різні типи даних.

Це обмеження, проте, не поширюється на покажчики, що не типізуються, тому ми могли б записати  

pp := p3;    

p1 := pp;

і тим самим досягти потрібного результату.  

Чи варто було вводити обмеження і тут же давати засоби для їх обходу? Вся річ у тому, що будь-яке обмеження, з одного боку, вводиться для підвищення надійності програм, а з іншої - зменшує потужність мови, робить його менш придатним для якихось вживань. У Турбо Паскалі нечисленні виключення відносно типів даних додають мові необхідну гнучкість, але їх використання вимагає від програміста додаткових зусиль і таким чином свідчить про сповна усвідомлену дію.

Виділення і звільнення динамічної пам'ятті    

Вся динамічна пам'ять в Турбо Паскалі розглядається як суцільний масив байтів, який називається купою. Фізично купа розташовується в старших адресах відразу за областю пам'яті, яку займає тіло програми.  

Початок купи зберігається в стандартній змінній HEAPORG (рис. 17.2), кінець - в тимчасовій HEAPEND. Поточний кордон незайнятої динамічної пам'яті вказує покажчик HEAPPTR.  

Пам'ять під будь-яку динамічно розміщувану змінну виділяється процедурою NEW. Параметром звернення до цієї процедури є покажчик, що типізується. В результаті звернення покажчика набуває значення, відповідне динамічній адресі, починаючи з якої можна розмістити дані, наприклад:  

var  

i, j : ^Integer;    

r : ^Real;    

begin   

New(i);  

.......  

end.  

Після виконання цього фрагмента покажчик і придбає значення, яке перед цим мав покажчик купи HEAPPTR, а сам HEAPPTR збільшить своє значення на 2, оскільки довжина внутрішнього представлення типа INTEGER, з яким пов'язаний покажчик і, складає 2 байти (насправді це не зовсім так: пам'ять під будь-яку змінну виділяється порціями, кратними 8 байтам). Оператор  

new(r);  

викличе ще раз зсув покажчика HEAPPTR, але тепер уже на 6 байт, тому що така довжина внутрішнього представлення типа REAL. Аналогічним чином виділяється пам'ять і для змінної будь-якого іншого типа.    


Рисунок 17.2. Розташування купи в пам'яті ПК  

Після того, як покажчик придбав деяке значення, тобто став вказувати на конкретний фізичний байт пам'яті, за цією адресою можна розмістити будь-яке значення відповідного типа. Для цього відразу за покажчиком без яких-небудь пропусків ставиться значок ^, наприклад:  

i^ := 2; {B область пам'яті i поміщено значення 2}    

r^ := 2*pi; {У область пам'яті r поміщено значення 6.28}  

Таким чином, значення, на яке вказує покажчик, тобто власне дані, розміщені в купі, позначаються значком ^, який ставиться відразу за покажчиком. Якщо за покажчиком немає значка ^, то мається на увазі адреса, по якій розміщені дані. Має сенс ще раз задуматися над тільки що сказаним: значенням будь-якого покажчика є адреса, а щоб вказати, що йдеться не про адресу, а про ті дані, які розміщені за цією адресою, за покажчиком ставиться л. Якщо Ви чітко з'ясуєте собі це, у Вас не буде проблем при роботі з динамічною пам'яттю.  

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

r^ := sqr(r)+ i - 17;  

Зрозуміло, абсолютно недопустимий оператор  

r := sqr(r)+ i - 17;  

оскільки покажчику R не можна привласнити значення речового вираження. Так само недопустимий оператор  

r := sqr(r);  

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

r^ :=i;  

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

Динамічну пам'ять можна не лише забирати з купи, але і повертати назад. Для цього використовується процедура DISPOSE. Наприклад, оператори  

dispose (r) ;    

dispose (i) ;  

повернуть в купу 8 байт, які раніше були виділені покажчикам I і R (див. вище).  

Відзначимо, що процедура DISPOSE(PTR) не змінює значення покажчика PTR, а лише повертає в купу пам'ять, раніше пов'язану з цим покажчиком. Проте повторне застосування процедури до вільного покажчика приведе до виникнення помилки періоду виконання. Покажчик, що звільнився, програміст може помітити зарезервованим словом NIL. Чи помічений який-небудь покажчик чи ні, можна перевірити таким чином:  

const  

p:  Real = NIL;  

begin  

.......  

if p = NIL then  

new(p);  

.......  

dispose(p);    

p := NIL;  

.......  

end.  

Жодні інші операції порівняння над покажчиками не дозволені.  

Приведений вище фрагмент ілюструє переважний спосіб оголошення покажчика у вигляді константи, що типізується, з одночасним привласненням йому значення NIL. Слід врахувати, що початкове значення покажчика (при його оголошенні в розділі змінних) може бути довільним. Використання покажчиків, яким не привласнено значення процедурою NEW або іншим способом, не контролюється системою і може привести до непередбачуваних результатів.  Чергування звернень до процедур NEW і DISPOSE зазвичай приводить до «комірчастої» структури пам'яті. Річ у тому, що всі операції з купою виконуються під управлінням особливої підпрограми, яка називається адміністратором купи. Вона автоматично пристиковується до Вашої програми компонувальником Турбо Паскаля і веде облік всіх вільних фрагментів в купі. При черговому зверненні до процедури NEW ця підпрограма відшукує найменший вільний фрагмент, в якому ще може розміститися необхідна змінна. Адреса початку знайденого фрагмента повертається в покажчику, а сам фрагмент або його частина потрібної довжини позначається як зайнята частина купи.

Інша можливість полягає в звільненні цілого фрагмента купи. З цією метою перед початком виділення динамічній пам'яті поточне значення покажчика HEAPPTR запам'ятовується в змінній-покажчику за допомогою процедури MARK. Тепер можна у будь-який момент звільнити фрагмент купи, починаючи від тієї адреси, яку запам'ятала процедура MARK, і до кінця динамічної пам'яті. Для цього використовується процедура RELEASE. Наприклад:  

var  

p,p1,p2,рЗ,р4,р5 : Integer;    

begin  

new(p1);  

new(p2);  

mark(p); .  

new(p3);  

new(p4);  

new(p5)

......  

release(p);   

end.  

В даному прикладі процедурою MARK(P) в покажчик Р було поміщено поточне значення HEAPPTR, проте пам'ять під змінну не резервувалася. Звернення RELEASE(P) звільнило динамічну пам'ять від поміченого місця до кінця купи. Рисунок 17.3 ілюструє механізм роботи процедур NEW-DISPOSE і NEW-MARK-RELEASE для розглянутого прикладу і для випадку, коли замість оператора RELEASE(P) використовується, наприклад, DISPOSE(P3).  

Слід врахувати, що виклик RELEASE знищує список вільних фрагментів в купі, створених до цього процедурою DISPOSE, тому спільне використання обох механізмів звільнення пам'яті в рамках однієї програми не рекомендується.  

Як вже наголошувалося, параметром процедури NEW може бути покажчик, що лише типізується. Для роботи з покажчиками, що не типізуються, використовуються процедури:  

GETMEM (P, SIZE) - резервування пам'яті;   

FREEMEM(P, SIZE) - звільнення пам'яті.  

тут Р - покажчик, що не типізується;  

SIZE - розмір в байтах необхідної або такої, що звільняється частини купи.    


Рисунок 17.3. Стан динамічної пам'яті: а) перед звільненням; би) після Dispose(p3); у) після Release(p)

За одне звернення до купи процедурою GETMEM можна зарезервувати до 65521 байта динамічної пам'яті.  

Використання процедур GETMEM-FREEMEM, як і взагалі вся робота з динамічною пам'яттю, вимагає особливої обережності і ретельного дотримання простого правила: звільняти потрібно рівно стільки пам'яті, скільки її було зарезервовано, і саме з тієї адреси, з якої вона була зарезервована.  

Неважко виявити, що наявність покажчиків, що не типізуються, в Турбо Паскалі (в стандартному Паскалі їх немає) відкриває широкі можливості неявного перетворення типів. На жаль, помилки в програмі, що важко виявляються, пов'язані з некоректно використовуваними зверненнями до процедур NEW і DISPOSE, також можуть привести до небажаного перетворення типів.

Питання для контролю.

1. Як описати покажчик?

2. В чому різниця між типізованим і не типізованим покажчиками?

3. Визначення купи.

4. Які є процедури для роботи з купою?

5. Як покажчику привласнити значення?


Тема 18: Процедури та функції для роботи з динамічною пам’яттю

Нижче приводиться опис як вже розглянутих процедур і функцій, так і деяких інших, які можуть виявитися корисними при зверненні до динамічної пам'яті.  

Функція ADDR.   

Повертає результат типа POINTER, в якому міститься адреса аргументу.

Звернення:  ADDR ( X )  

тут Х- будь-який об'єкт програми (ім'я будь-якої змінної, процедури, функції). Повертана адреса сумісна з покажчиком будь-якого типа. Відзначимо, що аналогічний результат повертає операція @ .  

Функція CSEG.  

Повертає значення, що зберігається в регістрі CS мікропроцесора на початку роботи програми в регістрі CS міститься сегмент початку кода програми).

Звернення:  CSEG    

Результат повертається в слові типа WORD.  

Процедура DISPOSE.   

Повертає в купу фрагмент динамічної пам'яті, який раніше був зарезервований за покажчиком, що типізувався.

Звернення:  DISPOSE(TP)  

тут ТР - покажчик, що типізується. При повторному використанні процедури стосовно вже звільненого фрагмента виникає помилка періоду виконання. При звільненні динамічних об'єктів можна вказувати другим параметром звернення до DISPOSE ім'я деструкції (детальніше за див. гл.10).  

Функція DSEG.   

Повертає значення, що зберігається в регістрі DS мікропроцесора (на початку роботи програми в регістрі DS міститься сегмент почала даних програми).

Звернення:  DSEG    

Результат повертається в слові типа WORD.

Процедура FREEMEM.   

Повертає в купу фрагмент динамічної пам'яті, який раніше був зарезервований за покажчиком, що не типізувався.

Звернення:  FREEMEM ( Р, SIZE )  

тут Р - покажчик, що не типізується;  

SIZE - довжина в байтах фрагмента, що звільняється.  

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

Процедура GETMEM.   

Резервує за покажчиком, що не типізується, фрагмент динамічної пам'яті необхідного розміру.

Звернення:  GETMEM ( Р, SIZE )  

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

Процедура MARK.   

Запам'ятовує поточне значення покажчика купи HEAPPTR.

Звернення:  MARK ( PTR )  

тут PTR - покажчик будь-якого типа, в якому буде повернено поточне значення HEAPPTR. Використовується спільно з процедурою RELEASE для звільнення частини купи.  

Функція MAXAVAIL.   

Повертає розмір в байтах найбільшої безперервної ділянки купи.

Звернення:  MAXAVAIL  

Результат має типа LONGINT. За один виклик процедури NEW або GETMEM не можна зарезервувати пам'яті більше, ніж значення, повертане цією функцією.  

Функція MEMAVAIL.   

Повертає розмір в байтах найбільшої безперервної ділянки купи.

Звернення:  MEMAVAIL

Результат має типа LONGINT.

Процедура NEW.   

Резервує фрагмент купи для розміщення змінної.

Звернення:  NEW ( ТР )  

тут ТР - покажчик, що типізується.  

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

Процедура NEW може викликатися як функція. В цьому випадку параметром звернення до неї є тип змінної, що розміщується в купі, а функція NEW повертає значення типа покажчик. Наприклад:  

type  

Pint =^Integer;    

var  p: Pint;    

begin  

p := New(Pint);  

......  

end.  

При розміщенні в динамічній пам'яті об'єкту дозволяється як другий параметр звернення до NEW вказувати ім'я конструктора.  

Функція OFS.   

Повертає значення типа WORD, що містить зсув адреси вказаного об'єкту.

Виклик:  OFS ( X )    

тут Х- вираження будь-якого типа або ім'я процедури.  

Функція PTR.   

Повертає значення типа POINTER по заданому сегменту SEG і зсуву OFS.

Виклик:  PTR ( SEG, OFS )  

тут SEG - вираження типа WORD, що містить сегмент;  

OFS - вираження типа WORD, що містить зсув.    

Значення, повертане функцією, сумісно з покажчиком будь-якого типа.  

Процедура RELEASE.   

Звільняє ділянку купи.

Звернення:  RELEASE ( PTR )   

тут PTR - покажчик будь-якого типа, в якому заздалегідь було збережено процедурою MARK значення покажчика купи. Звільняється ділянка купи від адреси, що зберігається в PTR, до кінця купи. Одночасно знищується список всіх вільних фрагментів, які, можливо, були створені процедурами DISPOSE або FREEMEM.  

Функція SEG.   

Повертає значення типа WORD, що містить сегмент адреси вказаного об'єкту.

Виклик:  SEG ( X )    

тут X - вираження будь-якого типа або ім'я процедури.  

Функція SIZEOF.   

Повертає довжину в байтах внутрішнього представлення вказаного об'єкту.

Виклик:  SIZEOF ( X )    

тут X - ім'я змінної, функції або типа. Замість константи SIZEOFREAL можна було б використовувати звернення SIZEOF(REAL).

Питання для контролю.

1. Призначення функції ADDR?

2. Призначення функції CSEG?

3. Призначення функції DISPOSE?

4. Призначення функції DSEG?

5. Призначення процедури FREEMEM?

6. Призначення процедури GETMEM?

7. Призначення процедури NEW?

8. Призначення процедури MARK?

9. Призначення процедур MAXAVAIL, MEMAVAIL?

10. Призначення процедури RELEASE?

11. Призначення функції SEG?

12. Призначення функції SIZEOF?


Тема 19: Символьний тип даних. Упаковані масиви

Дані символьного типу. Символьний тип приймає значення з усієї таблиці ASCII (256 символів).

Символьна константа – це символ, укладений в апострофи, наприклад:

'А', 'у', '?', '+', '', '4'.

Апострофи є ознакою символьної константи.

Щоб представити сам апостроф, його потрібно повторити двічі й укласти в апострофи: ’’’’.

Символьна константа займає один байт пам'яті. Її можна позначити ім'ям і задавати в розділі Соnst, наприклад:

const

simbol_1 = ‘A’

simbol_2 = ‘+’

Символьна змінна приймає значення одного символу, тобто одній змінній можна привласнити значення тільки одного символу. Змінна описується в розділі Var ключовим словом Char (символ), наприклад:

var

simbol : char;

.   .   .   .   .   .

simbol : 'А';

Кожен символ має код з діапазону 0 – 255 і може бути записаний кодовим представленням з попередньою вказівкою решітки (діеза): #10 – десятковий код, #$A – 16-річний код символу.

Кодом представляють символи, що не мають графічного зображення, наприклад – кінець рядка чи звуковий сигнал комп'ютера та ін.

При виведенні значень символьних даних можна використовувати формат. Наприклад:

writeln (a1, a2:2, a3:2);

Для розділення виведених значень символьних даних можна використовувати пробіл. Наприклад:

writeln (a1, ' ',a2, ' ',a3);

За причини того, що символи мови упорядковані, до символьних даних можна застосовувати операції відношень: <, <=, =, >=, >, <>.

'+' < '-';

'*' > '4'.

Чим далі буква в списку алфавіту, тим вона більше. Тому, 'В' > 'А'; 'OКО'>'ОКА'.

Результатом операції порівняння є логічна константа True чи False. Наприклад, результатом операції 'D' < 'F' є значення True.

До символьних даних застосовні наступні убудовані функції:

Ord (X) – повертає ASCII-код символу X.

Наприклад Ord(‘R’) = 82.

Дізнатися значення можна, виконавши:

begin

writeln (ord(‘R’));

end.

чи в меню Debug виконавши команду Evaluate / Modify... (Ctrl + F4) і в поле Expression ввести Ord(‘R’). У поле Result одержимо 82.

Chr(N) – визначає символ по ASCII-коду N, наприклад, Chr(83) = ‘S’.

Pred(X) – повертає попередній символ ASCII відносно символу Х. Наприклад Рred(‘S’) = ‘R’.

Succ(X) – повертає наступний символ ASCII відносно символу Х. Наприклад Succ(‘R’) = ‘S’.

При використанні функції Pred(X) і Succ(X) повинні бути як попередній, так і наступний символ відносно Х, інакше значення цих функцій буде не визначено.

UpCase(‘X’) – перетворить латинські малі літери в прописні. Інші символи, у тому числі букви кирилиці, не перетворить.

Наприклад:

var

x : char;

begin

x : = UpCase(‘r’)

end.     Результат: R

Символьний рядок являє собою послідовність символів, укладених в апострофи. Це фіксований рядок. Наприклад:

‘Summa=’, ‘Гімназія юридичного профілю’, ‘Результат’.

Максимальна довжина рядка 255 символів. Рядок можна позначити ім'ям у розділі констант, наприклад:

const

st1='Обсяг'

. . . . .

begin

  . . . . . .

writeln('Обсяг')

  . . . . .

end.

або використовувати її явно в розділі операторів, наприклад:

begin

. . . . .

writeln('Обсяг')

. . . . .

end.

При виконанні програми в обох випадках буде виведений рядок 'Обсяг'.

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

'ПРИКЛАД' = 'ПРИКЛАД', але 'ABC' < > 'ACB', тому що при порівнянні других символів 'В' < 'С';

' ПРИКЛАД ' > 'ПРИКЛАД', тому що в першому рядку на один пробіл більше, ніж у другому.

Змінній неможна привласнити значення фіксованого рядка, тому що фіксований рядок – це константа, і запис

var

s : char;

. . . .

s := 'Обсяг'

неприпустимо. Змінній можна привласнити тільки значення одного символу. Але не слід плутати символьний рядок зі строковими типами даних, що розглянемо в наступній лекції.

Приклад. Дано дві строкові константи “ДОН” і “СОН”.  Чи рівні вони?

const

s1 = ‘ДОН’;

s2 = ‘СОН’;

var

k1 : integer; {порядковий номер символу “Д”}

k2 : integer; {порядковий номер символу “С”}

l : boolean;

begin

k1 := ord('Д'); k2 := ord('С');

l := s1 < s2; {допустимо, сон менше дон, тобто l=true}

writeln('Порядковий номер символу “Д=”, k1:4);

writeln(‘Порядковий номер символу “С=”, k2:4);

writeln(‘Стіл менше стільця? ‘, 1)

end.

Виконавши програму, переконаємося, що L у результаті порівняння s1<s2 прийме значення True, тобто рядок “ДОН” менше рядка “СОН”, тому що символ “C” більше символу “L”.

Приклад. Визначити порядковий номер введеного символу, а також попередній і наступний символи.

var

s1, s2, s3 : char;

n : integer;

begin 

writeln('Введіть будь-який символ');

read(s1);

n := ord(s1);

s2 := pred(s1);

s3 := succ(s1);

writeln('Порядковий номер символу ', S1, '=', n:3);

writeln (‘Попередній символ -’, S2);

writeln (‘Попередній символ -’, S3);

end.

Упаковані масиви.

Один символ у пам'яті ЕОМ займає 2 байти, але для його збереження досить одного байту. Тому використовують поняття упакованого масиву.

Упакований масив символьних змінних можна описувати або в розділі Var:

var ім'я масиву: packed array[t1]of char;

або в розділі Type:

type ім'я типу = packed array[t1] of char;

var ім'я змінної : ім'я типу;

де Packed (упакований) – службове слово, що вказує на те, що масив даних є упакованим; t1 – тип індексу.

Наприклад, рядок символів:

“Ми – студенти електротехнічного коледжу”

будемо вважати масивом, що складається з 39 символів (лапки умовно не враховуємо). Назвемо цей масив ім'ям Stroka, тоді його опис буде наступним:

type str=packed array[1..39] of char;

var stroka : str;

тут Str  –  тип масиву; Stroka –  змінна типу Str.

Один елемент масиву приймає значення одного символу:

Stroka[1] = 'М', Stroka[2] = 'и', Stroka[3] = ' ', ... , Stroka[39] = 'у'.

Символьні константи мають тип упакованих масивів.

Елементи символьних масивів можуть брати участь в операціях присвоювання і порівняння. Так, якщо символьний масив описаний

Type str = packed array[1..39] of char;

Var stroka : str;

то допустим оператор:

Stroka := ’Ми – студенти електротехнічного коледжу';

Введення елементів масиву виконується за допомогою процедури Read, що розташовують усередині циклу, наприклад:

i := 1;

while not eoln do

  begin

  read(stroka[i]);

  i := i+1;

  end;

де елементи масиву будуть приймати значення доти, поки не зустрінеться символ кінця рядка “Enter”; чи

for i := 1 to 39 do

read(stroka[i]);

де цикл виконується 39 разів. В обох випадках елементи приймуть наступні значення:

Stroka[1] = ’M’, Stroka[2] = ’и’, Stroka[3] = ’ ’, … Stroka[39] = ’у’.

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

Приклад. Дан рядок символів S1: “Я добре знаю Pascal”. Потрібно сформувати новий масив з ім'ям S2, що складається з рядка S1 з додаванням наприкінці знаку питання та знаку оклику.

type stroka = packed array[1..20] of char;

var s1,s2 : stroka; i, k: integer;

begin

writeln(‘Введіть рядок s1:’);

i := 0;

while not eoln do begin

i := i+1;

read(s1[i]);

end;

s2 := s1; s2[i+1] := ’?’; s2[i+2] := ’!’;

writeln(‘новий рядок s2: ’);

for k:=1 to i+2 do

write(s2[k]);

end.

Питання для контролю.

  1.  Які значення маже приймати символьний тип?
  2.  Що таке символьна константа і що є  її ознакою ?
  3.  Як використовуються в програмі символьні константи і символьні змінні?
  4.  Скільки байт пам'яті займає символьний тип?
  5.  Скільки значень приймає символьна змінна?
  6.  Кодове представлення символу і коли його потрібно використовувати?
  7.  Які операції застосовуються  до символьних даних?
  8.  Перелічте убудовані функції, застосовувані при обробці символьних даних?
  9.  Що таке символьний рядок? Його максимальна довжина.
  10.  Як у програмі використовується символьний рядок?
  11.  Які операції застосовні до символьних рядків?
  12.  Чи можна змінній привласнити символьний рядок?
  13.  Дано два символьні рядки: у якому випадку вони рівні; у якому не рівні?
  14.  Виведення елементів упакованого масиву.
  15.  Поняття упакованого масиву.
  16.  Опис упакованого масиву.
  17.  Операції над елементами упакованого масиву.
  18.  Введення елементів масиву.


Тема 20: Процедури та функції для обробки рядків

Строковий тип даних. Змінна типу String.

Усе раніше розглянуті типи даних могли зберігати тільки один об'єкт: чи символ число. У Turbo Pascal-і є тип даних для обробки ланцюжка символів – рядків. Цей тип даних займає проміжне положення між простими структурованими типами.

Для збереження рядків використовується змінна типу String (рядок), що складається з елементів типу Char. Оголошення її має вид:

var ім'я змінної : string[n];

де n – довжина рядка (кількість символів), що може зберігатися в цій змінній. За замовчуванням довжина рядка максимальна – 225 символів.

Приклад описів:

var str1 : string;

      str2 : string[10];

      str3 : string[64];

Змінну типу String можна обробляти як цілий рядок, чи як складену з окремих елементів типу Char. Значення, що привласнюються строковій змінний, полягають в апострофи:

str1 :='ми – ';

str2 :='учні';

str3 :='10-а класу';

Ці рядки можна об'єднати операцією конкатенації:

str4 :='ми -' + 'учні' + '10-а класу';

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

str1[1] :='А'{першим символом у рядок str1 занести 'А'}

str3[4] :='б' {четвертим символом у рядок str3 занести 'б'}

одержимо:

“А ми – учні 10-б класу”

До символів рядка застосовні всі операції, що і до змінної типу Char.

Рядки обробляються за допомогою наступних стандартних процедур і функцій.

Функція Length (Str) визначає довжину текстового рядка, що зберігається в перемінної Str. Наприклад.

var 

   str : string;

begin

   write ('Уведіть рядок:');

   readln (str);

   writeln (‘У цьому рядку’, length (str),’ символів.’  )

end.

Функція UpCase(Str[i]) перетворює латинську букву з рядкової в прописну в i-й позиції рядка, що зберігається в змінній Str. Рядок обробляється за допомогою циклу. Наприклад.

var 

            str : string; i : byte;

begin

   write (‘Уведіть рядок:’);

   readln (str);

  for i := 1 to length(str) do

      str[i] :=UpCase(str[i]);

   writeln(str)

end.

Функція Copy(Str,p,n) вирізає з рядка, що зберігається в змінній Str, фрагмент довжиною n символів, починаючи з позиції p. Наприклад.

var 

   str1, str2, str3, str4 : string;

begin

str1 := 'абракадабра';

writeln(str1);

str2 := copy(str1,2,4);

writeln(str2);

str3 := copy(str1,2,3);

writeln(str3);

str4 := copy(str1,3,3);

writeln(str4);

end.

Функція Pos(Frag,Str) виконує пошук фрагмента Frag у рядку Str. Якщо рядок містить фрагмент, то функція повертає номер позиції в рядку, з якої починається цей фрагмент; якщо такого фрагмента немає, - функція повертає 0. При пошуку символи фрагмента повинні збігатися із символами рядка; прописні і малі літери розрізняються, тобто «А» не ідентична «а». Наприклад.

var

   frag,str : string; position : byte;

begin

   write('Введіть слово: ');

   readln(str);

   write('Введіть фрагмент: ');

   readln(frag);

   position := pos(frag,str);

   if position <> 0 then

     writeln(‘Фрагмент’, frag,’ міститься в слові ‘,str,

                  ‘, починаючи з позиції ‘, position)

else

     writeln(‘Фрагмент’, frag,’ не міститься в слові ‘,str)

end.

Процедура Insert(Str1, str2,p) уставляє рядок Str1 у рядок Str2, починаючи з позиції р.

Процедура Delete(Str,p,n,) видаляє n символів рядка Str, починаючи з позиції р. Наприклад.

var

  str1, str2: string[20];

begin

  str1 := 'комп'ютеризація';

  writeln(str1);

  delete(str1,1,7);

Writeln(str1);

Delete(str1,3,2);

Writeln(str1);

str2:=’Г’;

Insert(str2,str1,1);

Writeln(str1);

str2:=’не’;

Insert(str2,str1,3);

Writeln(str1);

end.

Процедура Сoncat(str1, str2, . . str) виконує зчеплення рядків str1, str2,...str у зазначеному рядку. Результуючий рядок не повинен перевищувати 255 символів. Наприклад.

var

str1,str2:string;

begin

str1 := ’електро’;

Writeln(str1);

str2 := ’технічний коледж’;

Writeln(str2);

Writeln(‘новий рядок:’,concat(str1,str2));

end.

Питання для контролю

  1.  Змінна строкового типу.
  2.  Присвоєння значень строкової змінної.
  3.  Доступ до символів рядка.
  4.  Визначення довжини рядка.
  5.  Витяг фрагмента з рядка.
  6.  Пошук фрагмента в рядку.
  7.  Вставка одного рядка в інший.
  8.  Видалення символів з рядка.
  9.  Операція конкатенації рядків.


Тема 21: Структурований тип даних - безліч

Безліч – це структурований тип даних, що представляє обмежений, неупорядкований набір різних елементів однакового типу.

Кількість елементів в одній безлічі не повинна перевищувати 256.

У Pascal-і елементи безлічі задаються в квадратних дужках:

['а', 'd', 's', 'р'] чи [12, 10, 6, 17].

Елементи в одній безлічі не можуть повторюватися.

Безліч, що не містить елементів, називається порожньою і позначається так: [ ].

Елементи безлічі не можна вводити і виводити за допомогою процедур Read і Write. Значення безлічей задають в операторі присвоювання, наприклад:

x1 := [‘а', ‘d’, ‘s’, ‘р']; x2 := [ 12,10,6,17]

Для опису безлічі використовується слово Set Of (безліч з…). Опис повинен знаходитися або в розділі Type:

type ім'я типу = set of t;

var ім'я безлічі : ім'я типу;

або безпосередньо в розділі Var:

var ім'я безлічі : set of t;

де t базовий тип елементів безлічі. В якості базового типу можуть бути стандартні типи Byte і Char, а також перелічувальні та обмежені типи, утворені з них. Інші типи неприпустимі. Це по'язано з обмеженням безлічі в 256 елементів.

Приклад опису.

type a = set of 1..100;

var x1, x2, x3 : a;

тут елементами безлічі x1, x2, x3 можуть бути будь-як цілі числа від 1 до 100, наприклад:

x1 := [1,23,45,17,21,3]; x2 := [1,15,10,33]; x3 := [100];

Опис цих безлічей безпосередньо в розділі Var має вигляд:

var x1,x2,x3 : set of 1..100;

Нижче представлені операції, які можна виконувати над безлічами :

+

*

-

=

<>

<=

>=

in

об'єднання безлічей;

перетинання безлічей;

вирахування безлічей;

перевірка безлічей на рівність;

перевірка безлічей на нерівність;

перевірка безлічі на включення “міститься в”;

перевірка безлічі на включення “містить”;

перевірка на приналежність елемента безлічі.

Розглянемо операції на прикладах. Нехай дані безлічі:

a := [5,8,10,3]; b =: [2,8,3,17];

Об'єднанням безлічей А+В є нова безліч, кожен елемент якої належить або безлічі А або В, наприклад:

var a,b,c : set of byte;

x: byte;

begin

a := [5,8,10,3]; b:=[2,8,3,17]; c := a+b;

write(‘безліч з = ’);

write(‘[ ’);

 for x := 2 to 17 do

 if x in c then write(x,’,’);

 write(‘]’);

end.

Перетинанням безлічей А*В є нова безліч, що містить елементи, які належать безлічам А та В, наприклад:

var a,b,c : set of byte;

x : byte;

begin

a := [5,8,10,3]; b := [2,8,3,17]; c := a*b;

write(‘безліч з = ’);

write(‘[ ’);

 for x := 2 to 17 do

 if x in c then write(x,’,’);

 write(‘]’);

end.

Вирахуванням безлічей А-В є нова безліч, складена з елементів безлічі А, не приналежніх безлічі В, наприклад:

var a,b,c: set of byte;

x: byte;

begin

a := [5,8,10,3]; b := [2,8,3,17]; c := a - b;

write(‘безліч з = ’);

write(‘[ ’);

 for x := 3 to 10 do

 if x in c then write(x,’,’);

 write(‘]’);

end.

Безліч А=В, якщо елементи безлічі А та В однакові. Результат операцій логічного типу, True чи False, наприклад:

var a,b : set of byte;

res : boolean;

begin

a := [5,8,10,3]; b := [2,8,3,17];

if a = b then res := true else

res := false;

writeln(res);

end.

Перевірка безлічі на включення “міститься в“. Безліч А міститься в безлічі В, якщо всі елементи безлічі А маються в безлічі В. Результат операції А<=B логічного типу, True чи False, наприклад:

var a,b : set of byte;

res : boolean;

begin

a := [5,8,10,3]; b := [2,8,3,17];

 if a <= b then res := true else

res := false;

writeln(res);

end.

Перевірка безлічі на включення “містить”. Безліч А містить безліч В якщо всі елементи безлічі В маються в безлічі А. Результат операції А>=В логічного типу, True чи False, наприклад:

var a,b : set of byte;

res : boolean;

begin

a := [5,8,10,3]; b := [2,8,3,17];

 if a >= b then res := true else

res := false;

writeln(res);

end.

Перевірка на приналежність елемента безлічі. Операція Х in А служить для перевірки приналежності елемента базового типу Х безлічі А. Результат операції логічного типу, True, якщо належить, чи False, якщо не належить. Наприклад:

var a,b : set of byte;

res : boolean;

begin

writeln(‘уведіть ціле число n :’);

readln(n);

a := [5,8,10,3];

 if n in a then res := true else

res := false;

writeln(res);

end.

Питання для контролю

  1.  Поняття  безлічі у Pascal.
  2.  Максимальна кількість елементів у безлічі. Чи можуть повторюватися елементи в одній безлічі? А в двох і більш безлічей?
  3.  Зображення безлічі у Pascal. Порожня безліч.
  4.  Як у Pascal задають значення безлічей? Чи можна організувати введення – виведення елементів за допомогою процедур Read і Write?
  5.  Опис безлічей у програмі.
  6.  Яким типом може бути базовий тип елементів безлічі?
  7.  Перелічте операції над безлічами.
  8.  Операції об'єднання безлічей.
  9.  Операції перетинання безлічей.
  10.  Операція вирахування безлічей.
  11.  Операція перевірки безлічей на рівність і на нерівність.
  12.  Операція перевірки безлічей на включення “міститься в”.
  13.  Операція перевірки безлічей на включення “містить”.
  14.  Операція перевірки на приналежність якого-небудь значення безлічі.


Тема 22: Структурований тип даних – записи

Розглянемо список успішності учнів:

№ п/п Прізвище , ім'я Оцінки

1 Іванов Петро  4 5 5 5

2 Петров Сергій  4 4 5 4

3 Сидоров Віктор  4 4 4 5

Він складається з даних різних типів:

№ п/п – ціле число;

прізвище й ім'я – рядок;

оцінки – масив цілих чисел.

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

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

Запис і кожен елемент запису позначають іменами. Для списку успішності учнів можна ввести наступні позначення:

sap – ім'я запису ;

nom – порядковий номер;

fam – прізвище та ім'я;

oc – оцінки.

До елемента запису звертаються за допомогою імені запису та імені елемента, розділеними крапкою:

Sap.nom – ім'я елемента 1;

Sap.fam – ім'я елемента 2;

Sap.oc – ім'я елемента 3;

Опис запису має вид:

type ім'я типу = record

  ім'я елемента 1 : тип;

  .   .   .

  ім'я елемента n: тип;

 end;

var ім'я запису : ім'я типу;

Службові слова Record (запис) і End виконують роль операторних дужок, усередині яких описуються елементи запису. Елементи запису з їхнім описом називаються полями запису. Список успішності учнів буде  мати наступний опис:

 

type spisok = record

  nom : integer;

  fam : string[20];

  oc : array[1..4] of integer;

 end;

var sap : array[1..n] of spisok;

Тут spisok – ім'я типу; sap – змінна, що представляє собою масив типу spisok. Кожен елемент запису має свій опис: nom – змінна цілого типу, fam – рядок з 20 символів, ос – масив з 4-х цілих чисел.

Записи можна описувати безпосередньо в розділі змінних:

var ім'я запису : record

  ім'я елемента 1 : тип;

  .   .   .

  ім'я елемента n: тип;

 end;

Список успішності учнів буде мати наступний опис :

var sap = record

  nom : integer;

  fam : string[20];

  oc : array[1..4] of integer;

 end;

Елемент запису в програмі використовується як звичайна змінна, та її можна вказувати як у лівій частині оператора присвоювання, так і у вираженнях. Над елементами запису виконують ті операції, що припустимі для типу їхніх даних. Наприклад:

  1.  ввести значення порядкових номерів Read(Sap.nom);
  2.  обчислити середній бал оцінок

Sr_bal := (Sap.oc[1] + Sap.oc[2] + Sap.oc[3] + Sap.oc[4]) / 4;

Оператор приєднання With…do

При спільній обробці декількох полів можна скористатися оператором приєднання With…do, який дозволяє спростити звертання до полів запису. Ім'я запису виноситься в заголовок оператора приєднання, а в блоці Begin-End використовуються тільки імена полів, тобто без вказівки перед ім'ям поля імені змінної, що визначає запис.

Оператор приєднання має вид:

with ім'я запису do

begin

 оператори;

end;

Для нашого приклада оператор приєднання можна записати так:

with sap[i] do

begin

 read(nom);

sr_bal := (oc[1] + oc[2] + oc[3] + oc[4])/4;

end;

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

const n = 10; {кількість учнів у класі}

type

spisok = record

 fam : string[20];

 oc : array[1..4] of byte;

end;

var

uch : array[1..n] of spisok;  i, j, k, sum : integer;

begin

writeln(Уведіть список ‘,n,’ учнів:’);

  for i :=1 to n do

   begin

     writeln(‘прізвище ’,i,’-го учня:’);

     readln(uch[i].fam);

for j := 1 to 4 do

 begin

  writeln(j,’-я оцінка:’);

  readln(uch[i].oc[j]);

 end;

end;

 for i := 1 to n do

   begin

    with uch[i] do

     begin

      for j := 1 to 4 do sum := sum + oc [j];

      if sum=20 then

     begin

       write(‘Відмінник: ‘);

       writeln(fam); k := k+1;

     end;

    end;

   end;

 if k=0 then writeln(‘Відмінників немає’);

end.

Питання для контролю.

  1.  Поняття запису в Pascal-і.
  2.  Звертання до елементів запису.
  3.  Оголошення запису.
  4.  Яка роль службових слів Record і End?
  5.  Що таке поле запису?
  6.  Як використовується елемент запису в програмі?
  7.  Які операції можна виконувати над елементами запису?
  8.  Оператор приєднання, його опис і застосування.


Тема 23: Опис файлових змінних. Обробка типізованих файлів

Файл – це пойменована область пам'яті на зовнішньому носії, призначена для збереження даних.

Робота з файлом у мові Pascal складається з таких етапів: оголошення файлової змінної; зв'язування файлової змінної з іменем наявного файла або файла, що створюється; відкриття файла; обробка файла; закриття файла.

Файли класифікують за типом компонентів і за методом доступу до них. За типом компонентів розрізняють текстові та бінарні (двійкові) файли, а за методом доступу — файли послідовного і прямого доступу. Текстові файли призначені для збереження текстів (наприклад, текстів Pascal-програм), а бінарні файли використовуються для збереження даних різних типів.

Текстовий файл є сукупністю символьних рядків змінної довжини. Кожен рядок завершується маркером кінця рядка — спеціальною парою керуючих символів: #13 (повернення каретки) та #10 (переведення рядка). Наприкінці файла записується маркер кінця файла — керуючий символ #26 (рис. 23.1).

Рисунок 23.1. Текстовий файл, що є сукупністю рядків

Бінарні файли в мові Pascal поділяються на типізовані та нетитзовані. Типізований файл складається з компонентів одного типу. Кожний компонент має порядковий номер, номер першого компонента дорівнює нулю. Інформація в типізованих файлах зображується в тому самому вигляді, що і в пам'яті комп'ютера, і тому відпадає потреба у використанні керуючих символів типу кінця рядка або повернення каретки. Приклад зображення даних у файлі, що містить компоненти рядкового типу, наведено на рис. 23.2.

Рисунок 23.2. Текстовий файл, що містить компоненти рядкового типу

Нетипізований файл у мові Pascal розглядається як сукупність байтів. Компонентом нетипізованого файла вважається запис, довжина якого за замовчуванням становить 128 байт.

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

Синтаксис оголошення файлової змінної залежить від типу файла. Далі наведено синтаксис оголошення змінної текстового, типізованого та нетипізованого файла.

var <ім'я файлової змінної>: text;

var <ім'я файлової змінної>: file of <тип компонентів>;

var <ім'я файлової змінної>: file;

Для опису файлу використовуються службові слова File та Of, за яких випливає базовий тип елементів. Базовий тип може бути будь-як типом.

Файли повинні бути описані в програмі або явно в розділі Var, або з використанням розділу Type.

Оголошення файлів у розділі Var має вигляд:

Var ім'я файлової змінної : file of базовий тип;

наприклад,

Var

F1 : file of char; {файл символьних даних}

F2 : file of integer; {файл цілих даних}

F3 : file of real;  {файл дійсних даних}

Оголошення в розділі Type має вигляд:

type ім'я типу = file of базовий тип;

var ім'я файлової змінної : ім'я типу;

Операції обробки файлів можна розділити на настановні та завершальні, і операції введення-виведення.

Настановні та завершальні операції реалізовані у вигляді процедур:

Assign; Reset; Rewrite; Close.

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

Assign  (файлова змінна, 'повне ім'я зовнішнього файлу');

Наприклад, після виконання

begin

 assign (f1,’c: \ tp \ pasfiles \ d1.pas’);

…       

   

файлова змінна F1 буде зв'язана з дисковим файлом D1.pas, розташованим на диску С: у підкаталозі PASFILES каталогу ТР.

Після установки зв'язку між файловою змінною і зовнішнім файлом процедурою  Assign у програмі повинна іти процедури Reset чи Rewrite, які мають один параметр – файлову змінну:

Reset (файлова змінна);

чи

Rewrite (файлова змінна);

Ці процедури призначені для відкриття зовнішніх файлів. Наприклад, після виконання

begin

 assign (f1,’c:\tp\pasfiles\d1.pas’);  

reset(f1);

процедура Reset(f1) відкриє зовнішній файл d1.pas, тобто знайде його на магнітному носії, створить буфери для обміну з ним і установить поточний покажчик на початок файлу (на його нульовий елемент). Процедура Rewrite виконає ту ж операцію, що і процедура Reset. Різниця між ними наступна. При використанні процедури Reset зовнішній файл, що відкривається, повинен існувати на магнітному носії, інакше виникне помилка. Процедура Reset при відкритті зовнішнього файлу не стирає його дані.

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

Процедура

Close (файлова змінна);

закриває зовнішній файл і ліквідує створені буфери для обміну з ним. Після  цього файлову змінну можна зв'язати процедурою Assign з іншим зовнішнім файлом. Варто помітити, що при закінченні роботи програми автоматично закриваються всі відкриті в ній файли. Але явне закриття файлів процедурою Close є гарним стилем програмування.

Операції введення-виведення. Читання даних з файлу виконується за допомогою процедури Read. Загальний вид процедури:  

Read(файлова змінна, змінні);

 

тут ім'я файлової змінної, відкритої процедурою Reset чи Rewrite, за якою слідують змінні, в які будуть міститися значення, що зчитуються з зовнішнього файлу. Тип цих змінних повинен збігатися з базовим типом файлу, з яким зв'язана файлова змінна. Наприклад,

begin

assign (f1,’c: \ tp \ pasfil es \ d1.pas’)      

reset(f1);

read(f1,s);

після виконання процедури Read (f1,s), починаючи з поточної позиції покажчика файлу буде послідовно зчитуватися значення, що містяться в зовнішньому файлі d1.pas. Кожне прочитане значення буде привласнюватися перемінній S, а покажчик файлу буде зміщатися на наступну позицію.

Запис даних у файл виконується за допомогою процедури Write. Загальний вигляд процедури:

Write(файловий змінна, список виражень);

тут за файловою змінною випливає список виражень, тип яких повинен збігатися з базовим типом файлу, з яким зв'язана файлова змінна.

Крім процедур і функцій, розглянутих раніше, у мові Pascal визначено процедури, за допомогою яких можна видалити файл або перейменувати його, тобто виконати операції, властиві операційній системі. Для видалення файла використовують процедуру Erase, а для перейменування — процедуру Rename. Синтаксис зазначених процедур є таким:

Еrаsе(<файлова змінна>);

Rеnаmе(<файлова змінна>,<нове ім'я>);

Тут <нове ім' я> — рядок, який має задовольняти вимоги операційної системи щодо специфікації імен файлів. Під час виклику процедур Erase та Rename файл має бути закритим.

Нагадаємо, що в мові Pascal визначено два різновиди бінарних файлів: типізовані і нетипізовані файли. Типізований файл є послідовністю однотипних компонентів. Нетипізований файл можна відкрити лише як файл компонентів однакового розміру, тобто як файл однотипних компонентів. Компоненти бінарного файла нумеруються, але їх кількість не є наперед відомою, як у масивах. Між компонентами не записуються жодні роздільники. Такого поняття, як рядок, а отже, і маркер кінця рядка, для бінарних файлів не означено.

Зчитування з бінарних файлів здійснюється лише процедурою Read, а запис -лише процедурою Write. Застосування до бінарних файлів процедур Readln або Writeln є неприпустимим, оскільки для таких файлів не означено поняття рядка.

Питання для контролю.

  1.  Поняття файлу в Pascal-і.
  2.  З яких етапів складається робота з файлом у мові Pascal?
  3.  Типи файлів за методом доступу.
  4.  Класифікація файлів за типом компонентів.
  5.  Настановні та завершальні операції.
  6.  Операції введення-виведення.
  7.  Процедури видалення та перейменування файлів.


Тема 24: Послідовний та прямий доступ до файлів

На відміну від масиву довжина файлу не задається, а місце елемента не визначається індексом. Файл, структурно організований як послідовність  елементів, де кожен елемент стає доступним після перебору всіх попередніх елементів, називається послідовним. Файл, збережений на диску, називається зовнішнім чи вхідним файлом. У Pascal-програмі представником файлу є змінна файлового типу, що інтерпретує файл як нескінченний список значень того самого базового типу. Зі змінною файлового типу пов’язане поняття поточного покажчика файлу. Поточний покажчик – це схована змінна, тобто вона неявно описана разом з файловою змінною, і вказує на деякий конкретний елемент файлу. Графічна  інтерпретація файлу, пов'язаного з файловою перемінною має вигляд зображений на рис.24.1:

елемент  елемент  елемент  … елемент… …

Поточний покажчик

Рисунок 24.1. Графічна інтерпретація файлу

Читання з файлу чи запису у файл виконується  поелементно, причому записується чи зчитується той елемент файлу, що позначений поточним покажчиком. При цьому покажчик переміщується, указуючи той чи інший елемент. Всі елементи файлу пронумеровані; перший елемент має нульовий номер.

Компоненти бінарного файлу мають однаковий розмір. Цим зумовлені певні переваги бінарного файлу над текстовим. По-перше, стає можливим прямий доступ до компонентів файлу за їхніми номерами. Під прямим доступом розуміється можливість встановлювати файловий покажчик на заданий компонент без послідовного перебирання попередніх компонентів. По-друге, відкриття бінарного файлу процедурою Reset робить можливим як читання, так і запис довільних компонентів файлу без руйнації його вмісту. Це пояснюється тим, що модифікація кількох компонентів усередині бінарного файлу не призведе до зміни їх розміру, а отже, не потребуватиме зсуву інших компонентів. Нагадаємо, що процедура Rewrite також відкриває бінарний файл у режимі читання і запису, але при цьому вона знищує його вміст (якщо файл уже існував).

Прямий доступ до компонентів бінарного файлу в мові Pascal здійснюється за допомогою процедур та функцій, наведених у табл. 24.1.

Таблиця 24.1. Процедури та функції прямого доступу до компонентів файлів

Ім'я функції або процедури

Призначення

Seek(var f; n: Longint);

Переміщує файловий покажчик на компонент з номером n. Файл f має бути відкритий

Truncate(var f);

Видаляє всі компоненти файла f від поточного компонента до кінця файла

FilePos(var f): Longint;

Повертає номер запису, на який посилається файловий покажчик

FileSize(var f): Longint;

Повертає кількість компонентів файла f

Треба взяти до уваги, що процедури Seek, Truncate і функція FilePos не працюють з текстовими файлами.

Приклад 1

Обчислити кількість компонентів в файлі дійсних чисел, вивести вміст файлу на екран.

var

f: file of real;

a: real;

i: word;

begin

assign(f, ’abc.dat’);

reset (f);

writeln(‘в файлі ’,filesize(f), ‘ чисел’);

for i:= 1 to filesize(f) do

begin

read(f, a);

write(a, ‘ ’);

end;

close(f);

end.

Приклад 2

В файлі цілих чисел поміняти місцями максимальний та мінімальний елементи.

var

f: file of integer;

a, i, max, nmax, min, nmin: integer;

begin

assign(f, ’abc.int’);

reset (f);

for i:= 1 to filesize(f)-1 do

read(f, a);

if i=0 then

{початкове привласнення максимального}

{і мінімального значень і їх індексів}

begin

max:=a;   nmax:= i;

min:=a;   nmin:=i;

end

else

begin

{порівняння поточного значення з максимальним (мінімальним)}

if max<a then

begin

max:=a;   

nmax:= i;

end;

if min >a then

begin

min:=a;   

nmin:=i;

end

end

end;

{перезапис максимального і мінімального значень у файл}

seek(f, nmax);

write(f, min);

Seek(f,nmin);

write(f,max);

end.

Питання для контролю.

  1.  В чому різниця між прямим та послідовним доступом до файлу?
  2.  Які функції здійснюють прямий доступ?
  3.  Які процедури здійснюють прямий доступ?
  4.  Які з перелічених процедур і функцій не можна використовувати для текстових файлів?


Тема 25: Обробка не типізованих файлів

Файли, що не типізуються, оголошуються як файлові змінні типа FILE і відрізняються тим, що для них не вказаний тип компонентів. Відсутність типа робить ці файли, з одного боку, сумісними з будь-якими іншими файлами, а з іншою дозволяє організувати високошвидкісний обмін даними між диском і пам'яттю.   

При ініціації файлу, що не типізується, процедурами RESET або REWRITE можна вказати довжину запису файлу, що не типізується, в байтах.

Наприклад, так:   

var   

f: file;   

begin   

.......   

assign(f, ''myfile.dat'')    

reset(f,512);   

.......   

end.   

Довжина запису файлу, що не типізується, вказується другим параметром при зверненні до процедур RESET або REWRITE, як яке може використовуватися вираження типа WORD. Якщо довжина запису не вказана, вона приймається рівною 128 байтам.   

Турбо Паскаль не накладає яких-небудь обмежень на довжину запису файлу, що не типізується, за винятком вимоги позитивності і обмеження максимальної довжини 65535 байтами (ємкість цілого типа WORD). Проте для забезпечення максимальної швидкості обміну даними слід задавати довжину, яка була б кратна довжині фізичного сектора дискового носія інформації (512 байт). Більш того, фактично простір на диску виділяється будь-якому файлу порціями - кластерами, які залежно від типа диска можуть займати 2 і більш суміжних секторів. Як правило, кластер може бути прочитаний або записаний за один зворот диска, тому найвищу швидкість обміну даними можна отримати, якщо вказати довжину запису, рівну довжині кластера.

При роботі з файлами, що не типізуються, можуть застосовуватися всі процедури і функції, доступні файлам, що типізуються, за винятком READ і WRITE, які замінюються відповідно високошвидкісними процедурами BLOCKREAD і BLOCKWRITE. Для виклику цих процедур використовуються наступні пропозиції:   

BLOCKREAD (<ф .п . >, <буф> < [, <NN>] )     

BLOCKWRITE (<ф . п . >, <буф> < [, <NN>] )   

Тут <буф> - буфер: ім'я змінної, яка братиме участь в обміні даними з дисками;     

<D> - кількість записів, які мають бути прочитані або записані   за одне звернення до диска;     

<NN> - необов'язковий параметр, що містить при виході з процедури   кількість фактично оброблених записів.

За одне звернення до процедур може бути передано до N*recs байт, де RECS - довжина запису файлу, що не типізується. Передача йде, починаючи з першого байта змінної <буф>. Програміст повинен поклопотатися про те, щоб довжина внутрішнього представлення змінної <буф> була достатньою для розміщення всіх N*recs байт при читанні інформації з диска. Якщо при читанні вказана змінна <буф> недостатньої довжини або якщо в процесі запису на диск не виявиться потрібного вільного простору, виникне помилка введення-виводу, яку можна заблокувати, вказавши необов'язковий параметр <NN> (змінна типа WORD).   

Після завершення процедури покажчик зміщується на <NN> записів. Процедурами SEEK, FILEPOS і FILESIZE можна забезпечити доступ до будь-якого запису файлу, що не типізується.

Питання для контролю.

  1.  Які файли називаються не типізованими?
  2.  В чому переваги не типізованих файлів?
  3.  Де можна вказати довжину запису файлу?
  4.  Як залежить швидкість обміну даними від довжини запису файла?
  5.  які специфічні процедури використовуються для роботи з не типізованими файлами?


Тема 26: Робота з текстовими файлами

Текстові файли складаються з рядків довжиною від 0 до 256 символів. Для опису використовується стандартний тип Text:

var ім'я файлової змінної : text;

Після опису всі операції з текстовим файлом виконуються за допомогою файлової змінної. Для обробки текстових файлів використовують стандартні процедури: Assign; Reset; Rewrite; Close; Read; ReadLn; Write; WriteLn; Eoln; Eof; Append.

Процедура

 

Append(файлова змінна);

відкриває текстовий файл для розширення тобто наприкінці файлу можна додати текст.

За причини того, що число елементів файлу не задається, в Pascal введена ознака кінця файлу. Ознакою кінця файлу є наявність символу з кодом 26 (Ctrl+Z). Для визначення файлового покажчика використовується стандартна функція EoF. Викликається вона з одним параметром – файловою змінною:

EoF(файлова змінна);

і повертає логічне значення True, якщо досягнуто кінець файлу і False – у протилежному випадку. Наприклад, у циклі:

while not eof (файлова змінна) do

begin

end;

циклічна частина, укладена в операторні дужки, буде повторюватися доки не буде досягнуто кінця файлу.

Дані у файлі зберігаються в рядках. Для визначення кінця рядка використовуємо оператор циклу

while not eoln (файлова змінна) do

begin

end;

Приклад 1. Вивести латинський алфавіт у файл abc.txt.

var t : text;{t – файлова змінна типу text}

i: char;

begin

assign (t,’c:\tp\pasfiles\abc.txt’); {встановлює зв'язок файлової змінної t із}
                                                                    {зовнішнім файлом abc.txt}

rewrite(t);{використовуємо цю процедуру, тому що файлу abc.txt на}
                               {диску не було}

 for i := ’A’ to ‘Z’ do 

write(t, i,’ ‘);{виведення латинського алфавіту в створений процедурою}
                                       {rewrite дисковий файл abc.txt}

close(t);

end.

Приклад 2. Написати програму, що формує файл, компоненти якого є цілими числами.

var f : file of integer;

i : integer;

begin

 assign (f1,’c:\tp\pasfiles\primer1.dat’);

rewrite(f);

 repeat

  readln(i);

  write(f, i)

 until i = 99; {вихід з циклу при введенні числа 99}

close(f);

end.

Приклад 3. Читання з файлу. Мається файл primer1.dat цілих чисел. Визначити кількість нулів у ньому.

var f : file of integer;

i, n0 : integer;

begin

 assign (f1,’c:\tp\pasfiles\primer1.dat’);

reset(f);

 while not eof (f) do

 begin

  read (f, i);

if i=0 then n0 := n0+1;

 end;

close(f);

writeln(‘у файлі primer1.dat ‘,n0,’нулів’);

end.

Приклад 4. Мається файл abc.txt з англійським алфавітом. Роздрукувати букви алфавіту і їхню кількість.

var f : text;{t – файлова змінна типу text}

s : char; sum : byte;

begin

assign (f,’c:\ tp\ pasfiles\ abc.txt’);

reset(f);

 while not eof (f) do

 begin

  read (f, s);

write(s);

if s <> ’ ’ then {якщо символ не пробіл, то}

 sum := sum+1;

 end;

close(f);

writeln;

write(‘в англійському алфавіті ‘,sum,’букв’);

end.

Приклад 5. Створити текстовий файл primer2.txt з довільним текстом.

var f : text;

Str : string;

 begin

 assign (f1,’c:\tp\pasfiles\primer2.txt’);

rewrite(f);

 repeat

  readln(str);

  if str<>’ ’ then {перевірка: якщо рядок не порожній,}

  writeln(f, str);    {то писати у файл;}

 until Str=‘ ’;             {якщо введений рядок порожній, то вихід з циклу}

close(f);

end.

Приклад 5. Мається текстовий файл primer2.txt. Додати текст у його кінець.

var f : text;

str : string;

begin

 assign (f,’c:\tp\pasfiles\primer2.txt’);

append(f);

 repeat

  readln(str);

if str<>’ ’ then

  writeln(f, str);

 until Str=‘ ’;

close(f);

end.

Питання для контролю.

  1.  Представник файлу в Pascal-програмі.
  2.  Поняття поточного покажчика.
  3.  Оголошення файлу в Pascal-програмі.
  4.  Процедура Assign і виконувана нею операція.
  5.  Процедури Reset і Rewrite, місце в програмі і виконувані ними операції.
  6.  Процедура Close і виконувані нею операції.
  7.  Зчитування даних із зовнішнього файлу. Приклад.
  8.  Запис даних у файл. Приклад.
  9.  Текстові файли. Опис текстового файлу.
  10.  Процедури, застосовувані при роботі з текстовими файлами.
  11.  Функції EoF і EoLn, їхнє застосування.


Тема 27: Типізовані константи

У Турбо Паскалі допускається використання констант, що типізуються. Вони задаються в розділі оголошення констант таким чином:   

<ідентифікатор> : <тип> = <значення>   

Тут <ідентифікатор> - ідентифікатор константи;              

<тип> - тип константи;             

<значення> - значення константи.   

Константам, що типізуються, можна привласнювати інші значення в ході виконання програми, тому фактично вони є змінними з початковими значеннями.

Константа, що типізується, набуває вказаного в її оголошенні значення, тобто ініціюється, лише один раз: до моменту початку роботи програми. При повторному вході в блок (процедуру або функцію), в якому вона оголошена, ініціація константи, що типізується, не виробляється і вона зберігає те значення, яке мала до моменту виходу з блоку.   

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

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

Константи простих типів і типа String    

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

type   

colors = (white, red, black); { ------- Правильні оголошення: ----- }     

const   

Currcol colors = red;   

name String = ''Вірт Н.'';   

year Word =1989;   

x Real = 0.1;   

min Integer = 0;   

max Integer =10;   

days 1..31 = 1;   

answer Char = '' Y''; {------ Неправильні оголошення: ------ }   

mass : array [min..max] of Real; {Не можна використовувати константи, що типізуються, як кордони діапазону}   

а,b,c : Byte = 0; {Не можна використовувати список ідентифікаторів}   

var   NAMEF: String [22] = ''prog.pas''; {Не можна оголошувати константу, що типізується, в розділі змінних}

Константи - масиви    

Як початкове значення що типізується константи-масиву використовується список констант, відокремлених один від одного комами; список полягає в круглі дужки, наприклад:   

type   

colors ''= (white, red, black);     

const   

Colstr : array [colors] of String [5] =(''white'', ''red'', ''blaсk'');     

vector : array [1..5] of Byte = (0,0,0,0,0); .   

При оголошенні масиву символів можна використовувати ту обставину, що всі символьні масиви і рядки в Турбо Паскалі зберігаються в упакованому форматі, тому як значення масиву-константи типа CHAR допускається завдання символьного рядка відповідної довжини. Два наступні оголошення ідентичні:

const   

digit : array [0..9] of Char =   (''0'', Ч'',''2'',''3'',''4'',''5'',''6'', '' 7 '', '' 8 '', '' 9 '') ;   

digchr: array [0..9] of Char =0123456789'';   

При оголошенні багатовимірних констант-масивів безліч констант, відповідних кожному виміру, полягає в додаткові круглі дужки і відділяється від сусідньої безлічі комами. В результаті утворюються вкладені структури безлічі, причому глибина вкладення повинна відповідати кількості змін (розмірність) масиву. Сама внутрішня безліч констант зв'язується із зміною найправішого індексу масиву.

Константи - записи    

Визначення константи-запису має наступний вигляд:   

<ідентифікатор> : <тип> = (<сп.знач.полей>)   

Тут <ідентифікатор> - ідентифікатор константи;              

<тип> - тип запису;             

<сп.знач.полей> - список значень полів.   

Списком значень полів є список з послідовностей вигляду: ім'я поля, двокрапка і константа. Елементи списку відділяються один від одного двоєточиямі, наприклад:  

type   

point = record   

х, у : Real;    

end;   

vect = array [0..1] of point;     

month = (Jan, Feb, Mar, Apr, May, Jun, Jly, Aug, Sep, Oct, Nov, Dec);     

date = record   d : 1..31;   

m : month;    

у : 1900..1999    

end;   

const   

origon :point = (x :0; у : -1) ;   

line:vector = ((x:-3.1; у: 1.5), (x: 5.9; у: 3.0)) ;   

Someday: date = (d : 16; m : Mar; у : 1989);   

Поля повинні вказуватися в тій послідовності, в якій вони перераховані в оголошенні типа.

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

Константи - безліч    

Значення що типізується константи-безліч задається у вигляді правильного конструктора безлічі, наприклад:     

type   

days = set of 1. .31;   

digc = set of '' 0 '' . . '' 9 '' ;   

error = set of 1..24;     

const   

Workdays : days = [1..5, 8.. 12, 15.. 19, 22.. 26, 29, 30];   

Evendigits: digc = [''0'', ''2'', ''4'', ''6'', ''8''];   

Errorflag : error= [] ;         

Константи - покажчики  

Єдиним значенням що типізується константи-покажчика може бути лише NIL, наприклад:   

const     

pr : Real= NIL;

Питання для контролю.

  1.  Як задаються типізовані константи?
  2.  В чому різниця між типізованою константою та змінною?
  3.  В чому різниця між типізованою константою та константою?
  4.  Приведіть приклад константи простого типу.
  5.  Приведіть приклад константи-масиву.
  6.  Приведіть приклад константи-запису.
  7.  Приведіть приклад константи-безлічі.
  8.  Назвіть особливість константи-покажчика?


Тема 28: Поняття та робота з процедурами та функціями

При написанні програм часто приходиться зіштовхуватися із ситуаціями, коли однаковий набір операторів потрібно повторити кілька разів. У таких випадках раціонально використовувати підпрограми.

Підпрограма – це іменована логічно закінчена група операторів, яку можна викликати за ім’ям в різних місцях програми будь-яке число раз.

У Pascal-і підпрограми реалізовані у виді процедур і функцій.

Процедура – це іменована логічно незалежна частина програми, призначена для виконання визначених дій після однократного опису.

Для виконання дій, передбачених процедурою, її викликають по імені. Ім'я процедури використовується тільки для її виклику і його не можна використовувати як операнд у вираженнях.

Функція аналогічна процедурі, але відрізняється від неї тим, що з ім'ям функції пов'язується її значення, що передається в точку виклику. Ім'я функції можна використовувати у вираженнях як операнд.

Виділяють дві групи процедур і функцій:

  1.  Убудовані (стандартні), що є частиною мови і мають строго фіксовані імена. Зберігаються вони в бібліотечних модулях, що підключаються до програми Uses.
  2.  Процедури і функції обумовлені користувачем. Ті дії, що потрібно виконувати в різних місцях програми, можна описати у вигляді процедури чи функції, а потім звертатися до них по імені.

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

Опис процедури:

procedure ім'я (список формальних параметрів);

розділи описів;

розділ операторів;

end;

Опис функції:

function ім'я (список формальних параметрів) : тип результату;

Розділ опису;

Розділ операторів;

end;

Локалізація імен. Імена змінних не повинні збігатися з ім'ям процедури й усередині локального блоку повинні бути унікальні. Змінні усередині блоку називаються локальними. Змінні в глобальному блоці називаються глобальними.

Імена локальних і глобальних змінних можуть збігатися. У цьому випадку ім'я локальної змінної закриває відповідну глобальною змінну.

Параметри процедур і функцій. У списку формальних параметрів вказуються імена параметрів і їхній тип. Перед іменами змінних може бути var. Приклади.

procedure demo (x,y : real; var z : real);

function power (var i,j : integer; real; var c: char) : boolean;

Список формальних параметрів може бути відсутній, тобто припустимі процедури і функції без параметрів. Формальні параметри використовуються в тілі процедури без їхнього попереднього опису в розділі опису процедури.

При звертанні до процедури чи функції формальні параметри заміняються фактичними.

Приклад.

Обчислити ab (вираження ab заміняємо вираженням exp(b ln(a))):

Приклад використання процедури:

var a,b,c : real; {фактичні параметри}

procedure demo (var x,y,z : real);

begin

 if x>0 then z := exp(y*ln(x))

  else if x<0 then z := exp(y*ln(abs(x)))   

   else if  y = 0 then z := 1

     else z := 0;

end;

begin {Основна програма}

 writeln(‘Введіть значення a, b:’);

 read(a,b);

 demo(a,b,c); {при звертанні формальні параметри заміняються}
                                {фактичними}

 writeln(‘a^b=’,c:3:2);

end.

Приклад використання функції:

var a,b,c : real;{фактичні параметри}

function demo (var x, y: real) : real;

begin

 if x > 0 then demo := exp(y*ln(x))

  else if x<0 then demo := exp(y*ln(abs(x)))

   else if  y = 0 then demo := 1

     else demo := 0;

end;

begin {Основна програма}

 writeln(‘Dведіть значення a,b:’);

 read(a,b);

 writeln(‘a^b=’,demo(a,b):3:2);{при звертанні формальні параметри
                   заміняються фактичними}

end.

Виклик функції можна використовувати в списках параметрів оператора Write і Writeln. Для процедур це неможливо.

Як бачимо, імена фактичних параметрів можуть не збігатися з формальними, оголошеними при описі процедури чи функції; важливі їхній  порядок і збіг типу.

Параметрі-змінні і параметри-значення. Якщо в списку формальних параметрів процедури чи функції в описі присутнє зарезервоване слово Var, параметр називається параметр-змінної, якщо Var не є присутнім, параметр називається параметром-значенням.

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

Приклад.

function power (var x,y : real) : real;

c := power(a,b); {вірно}

c := power(1,4,b); {не вірно, потрібно тільки ім'я змінної}

Якщо опис такий:

function power(x,y:real) : real;

то

c := power(a,b); {вірно}

c := power(2/*a,b+1,5);{вірно}

2-і відмінність. Якщо формальний параметр описаний як параметр-змінна, то при звертанні до процедури чи функції всі дії, описані в блоці для даного параметра, виконуються безпосередньо над глобальною перемінною, що є відповідно фактичним параметром; у випадку параметра-значення ці дії виконуються не над глобальною перемінною, а над її копією.

Приклад.

var a,b : integer;{фактичні параметри}

procedure double(x : integer; var y : integer);

begin

x := x+x; y := y+y;

writeln(‘Подвоєні: x = ’,x,’ y = ’,у);

end;

begin

a := 1; b := 3;

writeln(‘Вихідні: x = ’,a,’ y = ’,b);

double(a,b);

writeln(‘Після звертання до процедури: x = ’,a,’ y = ’,b);

end.

Результат роботи:  Вихідні: x = 1, y = 3

       Подвоєні x = 2, y = 6

       Після звертання до процедури: x = 1, y = 6

Рекурсивні процедури і функції.

Процедура чи функція називається рекурсивної, якщо у своєму визначенні вона використовує посилання на саму себе.

Наприклад, n-факторіал можна визначити в такий спосіб:

1, якщо n = 0      При n = 1

n! = n(n-1)!, якщо n ≠ 0     1! = 1*0! = 1;

        При n = 2

        2!=2*1!=2*1*0!

Рекурсивна функція для обчислення факторіала,

function fact(n : word) : word;

begin

 if n = 0 then fact := 1 else

 fact := fact(n-1)*n;

end;

Поряд із прямою рекурсією можливий непрямий рекурсивний виклик. Наприклад:

procedure A

. . .

begin

. . .

 B;

   . . .

end;

procedure B

. . .

begin

. . .

 A;

. . .

end;

Непряма рекурсія при такому описі порушує основний принцип ТР: будь-який ідентифікатор перед застосуванням повинний бути описаний.

Щоб допустити можливість рекурсії в ТР вводиться випереджальний опис. Заголовок функції, на який передбачається посилання до опису, описується звичайним чином, а потім слідом за заголовком указується слово forward, що означає, що тіло даної процедури буде далі.

Наприклад.

procedure B;

forward;

procedure A;

. . .

procedure B;

Питання для контролю:

  1.  Що таке підпрограма і як вона реалізована в Pascal?
  2.  Визначення процедури і функції. Відмінність функції від процедури.
  3.  На які групи поділяються процедури і функції?
  4.  Опис процедури і функції.
  5.  Локалізація імен змінних.
  6.  Параметри процедур і функцій.
  7.  Параметри-змінні і параметри-значення. Відмінності.
  8.  Рекурсивні процедури і функції. Пряма і непряма рекурсія. Випереджальний опис.


Тема 29: Використання модуля CRT. Програмування клавіатури

При роботі з ТР у розпорядженні користувача є наступні стандартні модулі:

System

Dos

Crt

Printer

Pverlay

-містить опис убудованих процедур і функцій ТР (підключається автоматично)

-містить процедури і функції відповідні командам Dos

-містить процедури і функції, що дозволяють керувати екраном і клавіатурою.

-зв'язує текстовий файл із файловою змінною Lst і портом Lpt1;

-дозволяє організувати оверлейну структуру програм (перекриття в пам'яті);

Модулі окремих файлів з расширением.tpu

Graph.tpu

Graph3.tpu

- містить опис процедур і функцій, використовуваних у графічному режимі;

- забезпечує сумісність з 3-й версією ТР

Модуль Crt і його застосування. Для використання модуля в програмі варто підключити його в розділі Uses:

uses crt;

Після завантаження модуль знаходиться в ОЗУ.

Керування клавіатурою.

Функція keyPressed : boolean повертає True, якщо була натиснута клавіша, і False, якщо буфер клавіатури порожній.

Функція ReadKey : char зчитує код натиснутої клавіші.

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

{Використання  функції KeyPressed}

uses crt;

var сh : char;

procedure TestKey(var ch : char);

procedure If_Pressed;

begin

gotoXY(1, Where);

ClrEoL; 

Write(‘Клавіша натиснута!');

delay(500); gotoXY(1, Where);

ClrEoL; {очищення рядка}

ch :=  ReadKey;

   if ch = #0 then ch := ReadKey;

end;

begin {TestKey}

ch := #25;

if KeyPressed then If_Pressed

end;

begin {головна програма}

ClrScr; writeln(‘Для закінчення - кл. Esc’);

repeat

 TestKey(ch)

until ch = #27;

end.

{Використання процедури ReadKey. Визначення спеціальних символів}

uses crt;

var сh : char;

procedure GetKey(var ch:char);

begin

ch := ReadKey; {прийом першого символу}

gotoXY(1, Where);

ClrEol;

if ch = #0 then {якщо #0 то спецклавіша}

begin

 write(‘Спецклавіша’);

 ch := ReadKey;

 end else write(‘звичайна клавіша: ’,ch);

end;

begin

ClrScr;

writeln(‘Для закінчення - кл. Esc’);

 repeat

  getkey (ch)

 until ch = #27;

end.

Питання для контролю:

  1.  Назвіть стандартні модулі ТР. Підключення модулів у програмі.
  2.  Модуль Crt, керування клавіатурою.


Тема 30: Використання модуля CRT. Текстове виведення на екран. Програмування звукового генератора

Установка текстового режиму.

Процедура TextMode (Mode:word) установлює текстовий режим виведення  інформації. Параметр Mode задається ім'ям константи чи номером режиму
(табл. 30.1):

Таблиця 30.1. Текстові режими виведення інформації.

Ім'я константи

Номер режиму

Екран

Монітор

bw40

co40

bw80

co80

mono

font8x8

0

1

2

3

7

256

40x25

40x25

80x25

80x25

80x25

80/40x43

80/40x50

Ч/б, CGA, EGA

Кольор., CGA, EGA

Ч/б, CGA, EGA

Кольор., CGA, EGA

MDA, Hereales

Кольор., EGA

Кольор., VGA

Константа Font8x8 самостійно не застосовується і повинна додаватися до інших констант, наприклад:

TextMode(co80+font8x8); - установлюється режим со80, але кількість рядків не 25, а 43 чи 50.

Установка кольору та фону.

Процедура TextColor установлює колір символів. Колір задається назвою чи номером (табл. 30.2).

Таблиця 30.2. Номери та назви кольорів

Номер та назва кольору

Колір

Номер та назва кольору

Колір

0(Black)

1(Blue)

2(Green)

3(Cyan)

4(Red)

5(Magenta)

6(Brown)

7(LightGray)

-чорний

-синій

-зелений

-блакитний

-червоний

-фіолетовий

-коричневий

-сірий

8(DarkGray)

9(LightBlue)

10(LightGreen)

11(LightCyan)

12(LightRed)

13(LightMagenta)

14(Yellow)

15(White)

128(Blink)

-темно-сірий

-світло-сірий

-світло-зелений

-світло-блакитний

-світло-червоний

-світло-фіолетовий

-жовтий

-білий

-мерехтіння

Мерехтіння задається додаванням до кольору константи Blink:

TextColor(Blue+Blink);

Змінна TextAttr використовується для керування кольором символів, фону, режимом мерехтіння і застосовується за формулою:

TextAttr := колір _символу + 16*колір_фону [ + мерехтіння];

Колір символу = 0...15; колір фону = 0..7; мерехтіння = 128.

Змінна має тип byte, і біти в байті несуть наступну інформацію:

0 - синій компонент кольору символів;

1 - зелений компонент кольору символів;

2 - червоний компонент кольору символів;

3 - яскравість символів(1 - є, 0 - немає);

4 - синій компонент кольору фону;

5 - зелений компонент кольору фону;

6 - червоний компонент кольору фону;

7 - мерехтіння(1- є, 0 - немає).

Процедура TextBackGround (Color byte) установлює колір фону color=0..7.

Керування рядками.

Процедура ClrScr очищає екран чи поточне вікно і поміщає курсор у лівий верхній кут.

Процедура ClrEoL стирає всі символи в рядку, починаючи з поточної позиції курсору до кінця рядка.

Процедура DelLine видаляє рядок, у якому розташований курсор, при цьому нижчестоящі рядки переміщаються нагору на одну позицію.

Установка яскравості символів.

Процедура HighVideo установлює режим максимальної яскравості.

Процедура LowVideo скасовує максимальну яскравість і встановлює нормальний режим яскравості.

Процедура NormVideo відновлює той режим (колір символів, фон, мерехтіння), що був напочатку роботи програми.

Керування курсором.

Процедура GotoXY(x, y:byte) встановлює курсор у позицію X (стовпець) і Y (рядок) щодо поточного вікна.

Функції WhereX:byte і WhereY:byte визначає координати Х та Y місця розташування курсору.

Текстове вікно.

Процедура Window (x1,y1,x2,y2:byte) формує вікно і задається координатами x1, y1 - лівим верхнім і x2, y2 - правим нижнім кутом вікна. Після виконання Window вікно стає поточним.

Керування звуком.

Процедура Sound (Hz : word) включає динамік і генерує звук з частотою Hz.

Процедура NoSound скасовує Sound. Ця процедура обов'язково повинна бути після виконання процедури Sound, інакше динамік буде звучати і після виконання програми.

Процедура Delay (t:Word) виконує затримку часу t у мілісекундах (1000млск. = 1сек.).

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

{Використання процедур TextMode, TextColor, Window, TextBackGround, GotoXY, ClrScr, функції Delay}

uses crt;

var i:byte;

begin

TextMode(c80+Font8x8);

Window(30, 10, 50, 15);

 for i := 0 to 7 do begin

  TextBackGround(i);

  ClrScr;

  TextColor(i+1);

  GotoXY(3,3);

  writeln(‘Тло = ‘,i,’, колір =’,i+1);

  delay(2000);

 end;

end.

{Використання процедур InsLine, DelLine}

uses crt;

var i : byte;

begin

TextMode(co80);{режим CGA 80/25}

ClrScr;

writeln(‘Натисніть клавішу для переміщення ‘,

  ’рядка вниз.’);

ReadKey;

write(‘Переміщуваний рядок’);

 for i := 2 to 24 do begin

  InsLine; {переміщення рядка вниз додаванням порожнього}
                                 {рядка в позицію курсору}

  delay(100);

 end;

gotoXY(1,1);

writeln(‘Натисніть клавішу для переміщення’,

  ’рядка нагору.’);

ReadKey;

 for i:=2 to 24 do begin

      DelLine;{переміщення рядка нагору видаленням рядка в}
                                {поточній позиції курсору}

      delay(100);

 end;

delay(100);

end.

{Використання  змінної TextAttr}

uses crt;

var i : byte;

begin

TextBackGround(Black);

ClrScr;

for i := 0 to 7 do begin

 TextAttr := i + 8 + 16*i; {установка кольору фону і символів}

 Writeln(‘Номер кольору фону:’,i,’,номер кольору символів: ’,i+8);

 TextAttr := i + 8 + 16*i + Blink; {установка тих же кольорів, але з}
                                                                     {мерехтінням}

 Write(‘Те ж саме, але з мерехтінням’);

 Readkey;

 gotoXY(1,WhereY-1); 

end;

end.

{Використання підвищеної і нормальної яскравості}

uses crt; 

begin

ClrScr;

writeln(‘Початкова яскравість (фон чорний)’);

TextBackGround(Blue);

HighVideo; {включення високої яскравості}

Writeln(‘Включена висока яскравість (фон синій)’);

LowVideo; {вимикання високої яскравості}

TextBackGround(Brown);

Writeln(‘Виключена висока яскравість (фон коричневий)’);

NormVideo; {відновлення режиму до моменту початку роботи}
                                   {програми}

Writeln(‘Відновлені початкова яскравість і фон‘);

ReadKey;

end.

{Генерація музичної гами}

uses crt;

const

nota : array[0..7] of word = (262,294,330,349,392,440,494,524);

var i : byte;

begin

ClrScr;

TextBackGround(Blue);

GotoXY(30,2); write(‘Звучить гама:’);

 repeat

  for i := 0 to 7 do begin

   Sound(nota[i]);{звук включений}

   Delay(500);

   NoSound;{ звук виключений}

  end

 until KeyPressed;

end.

Питання для контролю:

  1.  Модуль Crt, установка текстового режиму.
  2.  Модуль Crt, установка кольору символів, фону, режиму.
  3.  Модуль Crt, керування рядками.
  4.  Модуль Crt, установка яскравості символів.
  5.  Модуль Crt, керування курсором.
  6.  Модуль Crt, текстове вікно.
  7.  Модуль Crt, керування звуком.


Тема 31: Графічні можливості TP 7.0. Використання бібліотеки Graph

Для одержання доступу до графічних процедур і функцій потрібно в розділі Uses підключити модуль Graph. Часто в роботі з графікою необхідні засоби модуля Crt, тому підключаємо і його:

uses crt, graph;

Файли типу .bgi дозволяють настроїтися на конкретний графічний адаптер: CGA, EGA, VGA.

Для ініціалізації графіки і переходу в графічний режим використовується процедура

InitGraph(var GraphDriver : integer; var GraphMode : integer; Path : string);

де змінна GraphDriver задає тип драйвера, що підключається, наприклад:


GraphDriver := EGA; (можна задати цифрою 3)

Приведемо найбільш розповсюджені драйвери (табл. 31.1).

Таблиця 31.1. Драйвери

Драйвер

Режим

Розмір

Файл

CGA (1)

CGACO, CGAHi

320x200 (640x200)

cga.bgi

EGA (3)

EGALo, EGAHi

640x200 (640x350)

egavga.bgi

VGA (9)

VGALo, VGAHi

640x200 (640x350)

egavga.bgi

Змінна GraphMode задає режим графіки, наприклад:

GraphMode := EGAHi;

у параметрі Path указується шлях до каталогу в якому містяться bgi-файл. У нас на комп'ютерах ці файли розташовані в каталозі

С:\ТР\BGI;

Для автовизначення графічного режиму потрібно змінній GraphDrive привласнити значення константи Detect, наприклад:

GraphDriver:=Detect;

Приклад.

uses Graph;

var Gm, Gd : integer; {драйвер і режим}

begin

Gd := Detect; {режим автовизначення}

InitGraph(Gd, Gm, 'c:\tp\bgi'); {ініціалізація графіки}

Для визначення помилок при ініціалізації графіки використовується функція GraphResult. Якщо після ініціалізації графіки її значення дорівнює 0, то помилок немає, інакше - є. Для видачі повідомлення про тип помилки використовується функція GraphErrorMsg, що перетворює результат функції GraphResult у повідомлення, виведене на екран процедурою Write. Функція має вигляд:

GraphErrorMsg(ErrorCode);

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

uses Graph;

var Gm, Gd : integer;

ErrorCode : integer; {зберігає номер помилки}

begin

Gd := Detect;

InitGraph(Gd,Gm,'c:\tp\bgi');

ErrorCode := GraphResult; {збереження результ. ініціал.}

if ErrorCode <> 0 then begin

 writeln('Помилка графіки: ',GraphErrorMsg(ErrorCode));

 Halt(1);

end;

.  .  .

Процедура CloseGraph застосовується, коли графічна програма завершує свою роботу чи коли потрібно вийти з графічного режиму в текстовий.

Виведення тексту в графічному режимі.

Зображення звичайно супроводжують різними поясненнями. Для виведення тексту використовують процедуру OutTextXY(x,y,text), де х, у - координати точки початку виведення тексту, text - константа чи змінна типу string. Процедура OutText(text) виводить текст, починаючи з поточного положення покажчика.

Для визначення типу шрифту, його напрямку і розміру, використовується процедура

SetTextStyle(font, direction, charsize);

де константа font задає шрифт і вибирається з таблиці 31.2.

Таблиця 31.2. Список констант для визначення шрифту.

Ім'я константи

Номер

Шрифт і файл, де він зберігається

DefaultFont

0

Матричний 8х8 (Graph.tru)

TriplexFont

1

Напівжирний (trip.chr)

SmallFont

2

Тонкий (ntt.chr)

SansSerifFont

3

Рубаний (sans.chr)

GothicFont

4

Готичний (goth.chr)

За замовчуванням задається шрифт №0.

Константа direction задає напрямок виводимих символів:

0 - горизонтальне;

1 - вертикальне (знизу нагору),

константа charsize задає розмір символів від 1 до 10.

Приклад. Демонстрація шрифтів.

uses Graph, Crt;

var

gd, gm : integer; i : word;

begin

gd := Detect;

InitGraph(gd, gm, ‘c:\tp\bgi’);

if GraphResult<>0 then Halt(1);

SetColor(2);

SetTextStyle(0,0,2);

OutTextXY(75, 10, ‘П Р И К Л А Д И    Ш Р И Ф Т І В’);

SetColor(3); SetTextStyle(0,0,1);

OutTextXY(120,140, ‘DefaultFont. Матричний шрифт 8х8 (за ‘,
                                 ‘замовченням)’);

SetColor(4); SetTextStyle(1,0,1);

OutTextXY(160,70,’TriplexFont(SetTextStyle(1,0,1))’);

   SetColor(5); SetTextStyle(2,0,5);

   OutTextXY(160,110, ‘SmallFont (SetTextStyle(2,0,5))’);

   SetColor(6); SetTextStyle(3,0,1);

   OutTextXY(160,130, ‘SansSerifFont(SetTextStyle(3,0,1))’);

   SetColor(7); SetTextStyle(4,0,4);

   OutTextXY(80,170, ‘GothicFont (SetTextStyle(4,0,4))’);

   SetColor(15); SetTextStyle(0,1,1);

   OutTextXY(300,250, 'Вертикальне виведення');

   ReadKey:

   CloseGraph;

end.

 

Для виведення числа потрібно його перетворити процедурою Str у рядок, а потім операцією “+” підключити його до рядку, що виводиться OutTextXY.

Наприклад:

. . .

max := 2.14;

str(max : 4:2,smax); {результат перетворення в smax}

OutTextXY(400,40 ‘Максимум = ‘+smax);

. . .

Можливості Graph

У графічному режимі є невидимий поточний покажчик СР (current pointer), що виконує ті ж функції, що і курсор у текстовому режимі. Система координат починається з верхнього лівого кута (координати 0,0). Значення Х збільшується зліва направо, а Y - зверху вниз. Екран представляється у вигляді прямокутного масиву адресуємих точок. Кількість точок по горизонталі і вертикалі різне для різних адаптерів. Максимальне значення координат можна визначити функціями

GetMax:integer і GetMax:integer.

Процедура ClearDevice очищає екран і поміщає СР у точку (0,0).

Для переміщення СР використовуються процедури:

MoveTo(x,y:integer) - переміщає поточний СР у точку X,Y;

MoveRel(dx,dy:integer) - переміщає СР на dX і dY точок щодо поточного СР.

Функції GetX:integer  і GetY:integer дають поточне положення СР.

Процедура PutPixel(x,y,color) виводить крапку в X,Y кольором color.

Функція GetPixel(x,y) повертає номер кольору пикселя в X,Y.

Процедура Line(x1,y1,x2,y2:integer) виводить лінію (X1,Y1 - початок лінії, x2,y2 - кінець лінії; РС у точці x2,y2).

Процедура LineTo(x,y) з'єднує крапку РС із крапкою X,Y і РС переходить у X,Y.

Процедура LineRel(dx,dy) зміщає РС у крапку X+dX, Y+dY і малює лінію (x,y,x+dx,y+dy).

Можна змінювати стиль зображуваних ліній використовуючи процедуру:

SetLineStyle(вид, зразок, товщина);

де параметр “вид” дозволяє задати лінію або 4-х стандартних типів, або за своїм зразком.

0 - безперервна лінія;

1 - крапкова;

2 - штрих-пунктирна;

3 - штрихова;

4 - дозволяє задати вид лини користувача. Для цього призначений параметр “зразок”:word, 2 байти якого задають тип лінії; параметр “товщина” задає товщину лінії в пикселях (1 - нормальна товщина, 3 - велика товщина).

Приклад. Побудова ліній користувача.

uses Graph, Crt;

var

gd, gm : integer; x1,x2,y1,y2: word; ch : char;

begin

gd := Detect;

InitGraph(gd,dm,'c:\tp\bgi');

 if GraphResult <> 0 then Halt(1);

Randomize;

 repeat

 ClearDevice;

 OutTextXY(200,10,’Випадкові лінії користувача’);

 OutTextXY(140,20,’Зміна лінії - будь-яка клавіша, Esc-вихід');

 SetLineStyle(4,Random(65535),1);

 Line(10,100,GetMaxX,100);

 ch := ReadKey;

 until ch = #27;

CloseGraph;

 end.

Зображення окружності, дуги еліпса й еліпса будується за допомогою наступних процедур:

окружність  Circle(x, y, R);

дуга  Arc(x, y, нач.знач.кута, кінц.знач.кута, R);

дуга еліпса й еліпс Ellipse(x, y, нач.знач.кута, кінц.знач.кута, Rx, Ry);

Розбивка окружності на сектори:

PieSlice(x, y, нач.знач.кута, кінц.знач.кута, R);

де X,Y:integer - центр окружності, чи дуги еліпса; “нач.знач.кута” і “кінц.знач.кута” – початковий і кінцевий кути в градусах, відлічувані від горизонтальної осі проти годинникової стрілки; R:word - радіус окружності чи дуги, Rx і Ry - півосі. Еліпс зображується при “нач.знач.кута”=0, ”кінц.знач.кута”=360.

Приклад побудови дуги, еліпса й окружності.

uses Graph,Crt:

var

gd, gm : integer; x,y :word;

begin

gd := Detect;

InitGraph(gd, gm, ’c:\tp\bgi’);

 if GraphResult<>0 then Halt(1);

x := GetMax div 2; {координати центра}

y := GetMax div 2; {фігур}

SetColor(2);

OutTextXY(230,10,’Побудова окружності’);

Circle(x,y,150);

ReadKey; ClearDevice;

OutTextXY(240,10,’Побудова еліпса’);

Ellipse(x,y,0,360,180,120);

ReadKey; ClearDevice;

OutTextXY(200,10,’Побудова еліптичної дуги’);

Ellipse(x,y,0,180,180,120);

ReadKey; ClearDevice;

OutTextXY(250,10,’Побудова дуги’);

Arc(x,y,0,180,GetMaxY div 3);

ReadKey;

CloseGraph;

end.

Зображення прямокутника (внутрішня область збігається з кольором з фону):

процедура Rectangle(x1,y1,x2,y2:integer), де X1,Y1 і X2,Y2 відповідно координати лівого верхнього і нижнього правого кута.

Зображення заштрихованого за шаблоном прямокутника:

процедура Bar(x1,y1,x2,y2:integer), де X1,Y1 і X2,Y2 - координати діагоналі.

Зображення паралелепіпеда, лицьова сторона якого заштрихована за поточним шаблоном, а глибина задається:

процедура Bar(x1,y1,x2,y2:integer,d3:word,top:boolean), де X1,Y1 і X2,Y2 - координати діагоналі передньої грані, d3 - глибина в пикселях, top - задає режим відображення верхньої площини: True - відображати, False - не відображати. Для цієї процедури в Graph визначені дві константи:

TopOn = true; {верхня площина відображається}

TopOff = false; {верхня площина не відображається}

{Приклад побудови прямокутника, паралелепіпеда без верхньої площини і з верхньою площиною}

uses Graph,Crt;

var

gd, gm : integer; x1, x2, y1, y2 : word;

begin

gd := Detect;

InitGraf(gd,gm,’c:\tp\bgi’);

 if GraphResult<>0 then Halt(1);

{координати вершин прямокутника по діагоналі}

x1 := GetMaxX div 4;

y1 := GetMaxY div 4;

x2 := 2*GetMaxX div 3;

y2:=GetMax div 5;

OutTextXY(210,50,’Звичайний прямокутник’);

OutTextXY(190,60,’(Продовження – будь-яка кл.)’);

Rectangle(x1,y1,x2,y2);

ReadKey; {в цьому випадку використовуємо як процедуру}

ClearDeviсe;

OutTextXY(210,50,’Залитий прямокутник’);

OutTextXY(190,60,’(Продовження – будь-яка кл.)’);

Bar(x1,y1,x2,y2);

ReadKey; ClearDevice;

OutTextXY(200,10,’Паралелепіпед без верхньої площини’);

OutTextXY(240,20,’(Продовження – будь-яка кл.)’);

Bar3D(x1,y1,x2,y2,(x2-x1) div 4, TopOff);

ReadKey; ClearDevice;

OutTextXY(200,10,’Паралелепіпед з верхньою площиною’);

OutTextXY(250,20,’(Вихід – будь-яка кл.)’);

Bar3D(x1,y1,x2,y2,(x2-x1) div 4, TopOn);

ReadKey;

CloseGraph;

end.

Завдання кольору ліній і тексту  SetColor(color);

Завдання кольору фону SetBkColor(color);

Приклад керування кольором букв і фону.

uses Graph,Crt;

var

gd, gm : integer; ch : char; i : word;

begin

gd := Detect;

 if GraphResults<>0 then Halt(1);

Randomize;

 repeat

 SetBkColor(i); SetColor(Random(GetMaxColor));

 OutTextXY(190,10,’Послідовний перебір кольору фону’);

 OutTextXY(210,20,’(Вибір кольору букв - випадковий)’);

 OutTextXY(180,30,’(Продовження – будь-яка кл., вихід - Esc)’);

 if i < GetMaxColor then inc(i)

 else i := 0;

 until ch = #27;

CloseGraph;

end.

Для зображення ламаних ліній, що задаються крапками зламу, використовується процедура

DrawPoly(кількість, координати);

Де ”кількість” - кількість крапок зламу, ”координати” - їхні координати. Координати задаються у виді масиву, кількість компонентів якого дорівнює кількості крапок зламу, а кожен компонент типу запис:

PointType=record

x, y : integer;{координати крапок}

end;

Процедура DrawPoly малює ламану лінію. Для одержання багатокутника потрібно першу та останню крапку зламу з'єднати.

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

uses Graph, Crt;

type

 PointType = record

 x,y : integer; {координати крапок}

 end;

var

gd, gm : integer; i : byte; ch : char;

points : array[1..6] of pointtype; {масив вершин}

begin

gd := Detect;

InitGraph(gd,gm,’c:\tp\bgi’);

 if GraphResults <> 0 then Halt(1);

Randomize;

SetColor(2);

OutTextXY(140,10,’Побудова випадкових кольорових багатокутників’);

SetColor(4);

OutTextXY(100,20,’(Для продовження – будь-яка кл., вихід - Esc)’);

ch := ReadKey;

 if ch = #27 then begin

 ClearDevice; Halt;

 end;

 repeat

  ClearDevice;

   for i := 1 to 6 do begin

   {визначення випадкових координат} 

    points[i].x := Random(GetMaxX); 

    points[i].y := Random(GetMaxY); 

   end;

 {для одержання багатокутника з'єднуємо}

 {координати першої та останньої вершини}

  points[6].x := points[1].x;

  points[6].y := points[1].y;

  SetColor(Random (15)+1);{вибір випадкового кольору}

  DrawPoly(6, points); {будуємо багатокутник}   

  сh := ReadKey;

 until ch = #27;

CloseGraph;

end.

Модуль Graph. Штрихування геометричних фігур.

Процедура для штрихування заданим стилем:

FloodFill(x,y, колір контуру);

де (x,y) - координати точки усередині замкнутого контуру чи поза ним. Штрихування складних геометричних фігур, що задаються координатами в масиві:

FillPoly(кількість, координати);

де ”кількість” - кількість крапок зламу, ”координати” - їхні координати. Координати задаються так само як у процедурі DrawPoly, але зв'язувати першу та останню вершини не потрібно, тому що процедура FillPoly малює замкнутий багатокутник, тобто перша та остання вершини з'єднуються відрізком.

Зображення заштрихованого еліпса:

FillEllipse(x,y,Rx,Ry);

де (x,y) - координати центра еліпса, Rx і Ry - півосі.

Завдання зразка штрихування:

SetFillStyle(тип штрихування, колір);

Тип штрихування обирається по таблиці 31.3.

Таблиця 31.3. Список констант для штрихування геометричних фігур.

Константа

Тип штрихування

Константа

Тип штрихування

0

Колір фону

7

Клітка

1

Поточний колір

8

Коса рідка клітка

2

-------

9

Коса часта клітка

3

//нормальна товщина

10

Рідка крапка

4

//подвоєна товщина

11

Часта крапка

5

\\подвоєна товщина

12

Визначення користувачем

6

\\нормальна товщина

Приклад штрихування фігур.

uses Graph,Crt;

type PointType=record

x, y : integer;

end;

var

gd, gm : integer; i, x1, x2, y1, y2 : word;

points : array[1..4] of PointType;

begin

gd := Detect;

InitGraph(gd, gm, ’c:\tp\bgi’);

 if GraphResults<>0 then Halt(1);

OutTextXY(240,10,’Кругова діаграма’);

SetColor(1); SetLineStyle(0,0,3); {стиль лінії}

SetFillStyle(10,2); {вибір стилю заповнення}

PieSlice(GetMaxX div 2, GetMaxY div 2, 47, GetMaxY div 3);

SetFillStyle(11,4);

PieSlice(GetMaxX div 2, GetMaxY div 2, 47, 170, GetMaxY div 3);

SetFillStyle(9,5);

PieSlice(GetMaxX div 2, GetMaxY div 2, 170, 210, GetMaxY div 3);

SetFillStyle(8,6);

PieSlice(GetMaxX div 2, GetMaxY div 2, 210, 260, GetMaxY div 3);

SetFillStyle(7,7);

PieSlice(GetMaxX div 2, GetMaxY div 2, 260, 360, GetMaxY div 3);

ReadKey; ClearDevice; SetColor(2);

OutTextXY(240,10,’Заповнення еліпса’);

SetFillStyle(1,8);

FillEllipse(GetMaxX div 2,GetMaxY div 2, 200, 150);

ReadKey; ClearDevice; SetColor(3);

OutTextXY(220,10,’Заповнення еліптичного сектора’);

SetFillStyle(6,4);

Sector(GetMaxX div 2,GetMaxY div 2, 45, 90, 200, 150);

ReadKey; ClearDevice;

OutTextXY(250, 10, ‘Заповнення граней паралелепіпеда’);

x1 := GetMaxX div 4;

y1 := GetMaxY div 3;

x2 := 3*GetMaxX div 4;

y2 := 2*GetMaxX div 3;

SetColor(2); SetFillStyle(2,4);

Bar3D(x1, y1, x2, y2, (x2-x1) div 4, TopOn);

SetFillStyle(6,3);

SetFillStyle(3,4);

FloodFill(x1+50,y1-10,2);

FloodFill(x2+10,y2-50,2);

ReadKey; ClearDevice;

OutTextXY(220, 10, ’Заповнення прямокутника’);

points[1].x := GetMaxX div 3;

points[2].x := 2*GetMaxX div 3;

points[3].x := 2*GetMaxX div 3;

points[4].x := GetMaxX div 3;

points[1].y := GetMaxY div 3;

points[2].y := GetMaxY div 3;

points[3].y := 3*GetMaxY div 3;

points[4].y := 3*GetMaxY div 3;

FillPoly(4, Points);

ReadKey;

CloseGraph

end.

Збереження і виведення зображень на екран. Одержання зображення, що рухається.

Модуль Graph дозволяє запам'ятовувати в буфері і відновлювати з нього фрагменти зображень на екрані. Зображення для збереження міститься в динамічну область пам'яті, розмір якої повинний відповідати розміру зображення в прямокутній області екрана в байтах.

Для обчислення розміру використовують функцію:

ImageSize(x1, y1, x2, y2:integer):word;

де X1,Y1 і Х2,Y2 - координати лівого верхнього і правого нижнього кутів прямокутника частини екрана, у якому розташоване зображення. Розмір зображення, що зберігається, не повинний бути більш 64 kb.

Для збереження зображення процедурою GetMem в області динамічної пам'яті виділяють буфер обчисленого розміру:

GetMem(p,Size);

де p - виділений буфер, Size - його розмір у байтах.

Зображення частини екрана міститься в буфер (р^) за допомогою процедури:

GetImage(x1, y1, x2, y2, p^);

де Х1, У1, Х2, У2 - координати фрагмента.

Процедура

PutImage(x, y, p^, вид);

виводить на екран раніше збережене в буфері (р^) зображення, де Х, У -координати лівого верхнього кута виведеного зображення;

параметр “вид”:word визначає яким чином виводиться зображення щодо наявного на екрані. Значення цього параметра наступні (задається ім'ям чи значенням):

NormalPut = 0  - очищується область і виводиться зображення;

XorPut = 1  - зображення затирається, а при повторному використанні виводиться  в іншому (в заданому) місці;

OrPut = 2  - накладення зображення;

AndPut = 3  - перетинання двох зображень;

NotPut = 4  - зображення негативне.

Отже, одержання зображення, що рухається, зводиться до наступних – операцій (рис. 31.1).

(x1, y1)

(x2,y2)

Рисунок 31.1. Одержання зображення, що рухається

Size := ImageSize(x1,y1,x2,y2);- визначаємо розмір зображення в байтах;

GetMem(p,Size); - виділяємо область динамічної пам'яті для збереження зображення;

GetImage(x1,y1,x2,y2,p^); - поміщаємо зображення у виділену пам'ять (у р^);

PutImage(x1,y1,p^,1); - затираємо зображення;

PutImage(x2,y2,p^,1) - малюємо зображення в іншім місці.

Приклад руху фігури.

uses Graph, Crt;

var

gd, gm : integer;

Size : word; x1, y1, x2, y2 : word; p : pointer;

begin

gd := Detect;

InitGraph(gd, gm, ’c:\tp\bgi’);

 if GraphResult <> 0 then Halt(1);

OutTextXY(120,1,’Одержання зображення, що рухається,‘,
‘(натисни будь-яку клавішу)’);

ReadKey;

{координати прямокутника}

x1 := GetMax div 300; y1 := GetMax div 200;

x2 := GetMax div 10; y2 := 2*GetMax div 10;

{малюємо прямокутник}

Rectagle(x1,y1,x2,y2);

Size := ImageSize(x1,y1,x2,y2);

GetMem(p,Size);

GetImage(x1,y1,x2,y2,p^);

{затираємо зображення}

PutImage(x1,y1,p^,XorPut);

{малюємо зображення в іншому місці}

PutImage(x2+500,y2+250,p^,1); {замість XorPut можна ставити 1}

ReadKey;

CloseGraph;

end.

Питання для контролю:

  1.  Доступ до графічних процедур і функцій.
  2.  Ініціалізація графіки і перехід у графічний режим.
  3.  Автовизначення графічного режиму.
  4.  Визначення і видача помилок при ініціалізації графіки.
  5.  Виведення тексту в графічному режимі.
  6.  Виведення числа в графічному режимі.
  7.  Система координат і визначення максимальної кількості по осях.
  8.  Очищення графічного екрана.
  9.  Визначення поточного положення покажчика і його переміщення.
  10.  Виведення крапки заданого кольору.
  11.  Побудова ліній.
  12.  Зображення окружності, дуги, дуги еліпса й еліпса.
  13.  Зображення прямокутника.
  14.  Зображення заштрихованого за шаблоном прямокутника.
  15.  Зображення паралелепіпеда з заштрихованою лицьовою стороною.
  16.  Завдання кольору ліній, тексту і фону в графічному режимі.
  17.  Зображення ламаних ліній, що задаються крапками зламу.
  18.  Штрихування геометричних фігур заданим стилем.
  19.  Зображення заштрихованого еліпса.
  20.  Завдання зразка штрихування.
  21.  Визначення розміру зображення.
  22.  Виділення буферу в області динамічної пам'яті для збереження зображення.
  23.  Переміщення зображення у виділений буфер динамічної пам'яті.
  24.  Виведення на екран збереженого в буфері зображення.
  25.  Операції одержання зображення, що рухається.


Тема 32: Бібліотечні модулі користувача

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

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

Використання модулів дозволяє зняти обмеження в 64 kb на обсяг програми і даних, а також дозволяє автономно налагоджувати окремі фрагменти програмного проекту, підключаючи їх потім до основної програми.

Створення модуля вимагає визначеної організації з застосуванням слів Unit, Interface, Implementation, Begin, End.

Загальна структура модуля.

unit ім'я бібліотечного модуля;

{$N+}  - директиви компілятора;

interface  {интерфейсная секція}

uses   - використовувані при оголошенні модулі;

label  - оголошення глобальних міток;

const  - оголошення глобальних констант;

type  - оголошення глобальних типів;

var  - оголошення глобальних змінних;

procedure  - заголовки процедур із вказівкою параметрів;

function  - заголовки функцій із вказівкою параметрів;

implementation {секція реалізації}

uses  - використовувані при реалізації модулі;

label  - оголошення локальних міток;

const  - оголошення локальних констант;

type  - оголошення локальних типів;

var  - оголошення локальних змінних;

procedure  - заголовки і тіло процедур;

function  - заголовки і тіло функцій;

begin {ініціалізаційна частина}

оператори;

end.

Ім'я бібліотечного модуля повинне збігатися з ім'ям дискового файлу, де знаходиться вихідний текст модуля. Наприклад, якщо файл має ім'я My_Lib.pas, то модуль повинен бути

unit My_Lib;

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

У секції реалізації можуть підключатися модулі, а також міститися описи міток, констант, типів, змінних, процедур і функцій, що є локальними, тобто вони доступні тільки для даного модуля і недоступні основній програмі. Тут описуються тіла процедур і функцій, заголовки яких містилися в інтерфейсній секції, причому їхній порядок повинний збігатися. Заголовки процедур і функцій можна вказати повністю, у цьому випадку вони повинні точно збігатися з тими заголовками, що були в інтерфейсній секції, а можна вказувати коротко, тобто після слова procedure чи function указати тільки ім'я.

Наприклад:

. . .

interface

function fact(n : integer) : word;

procedure a(var x : real);

implementation

uses crt;

function fact(n:integer):word;

begin

. . .

end;

procedure a;

begin

. . .

end;

. . .

Реалізаційна секція також може бути порожньою.

Ініціалізаційна частина є основним блоком модуля. Оператори цього блоку виконуються першими, а потім виконуються оператори основного блоку головної програми, до якої включено даний модуль.

Для підключення модуля до основної програми відразу після імені програми вказують

uses ім'я модуля;

Припустима вкладеність модулів, причому обмеження на їхній ступінь не накладається.

Компіляція модуля.

Після підготовки вихідного тексту його можна відкомпілювати. Для цього варто встановити в режимі меню Compile опцію Destination у стан Disk. У результаті компіляції (Alt+F9) створюється файл із тим же ім'ям, що і вихідний текст, але з розширенням .tpu.

Можна одночасно компілювати програму і модулі, що підключаються, створивши ехе-файл. Для цього в меню Compile вибираємо чи режим Make, чи Build.

У режимі Make компілюються ті модулі, для яких не мається tpu-файлу, чи якщо tpu-файл “старіше”, ніж відповідний йому pas-файл.

У режимі Build компілюються і підключаються всі модулі, імена яких містяться в реченнях Uses.

У меню Options пункт Directories дозволяє контролювати каталоги в які посилаються відкомпільовані файли:

в опції EXE & TPU directory варто вказати

с:\tp\exe&tpu - куди посилаються ехе і tpu-файли;

в опції Unit directories варто вказати

c:\tp\units; c:\tp\exe&tpu - звідкіля брати tpu-файли (таких каталогів може бути декілька).

Приклад який показує, що спочатку виконується оператор ініціалізаційної частини включеного модуля, а потім оператори головної програми.

Створимо модуль Unit demo_tpu з одним оператором ClrScr, що очищає екран:

unit demo_tpu;

interface

{ця частина порожня}

implementation

uses crt;

begin

clrscr;

end.

і запишемо його під ім'ям demo_tpu.pas. Відкомпілювавши його, одержимо модуль demo_tpu.tpu.

Створимо програму, у якій використовуємо цей модуль

{демонстрація використання модуля demo_tpu.tpu}

uses demo_tpu;

begin

writeln(‘Першим виконався оператор основного’);

writeln(‘блоку модуля demounit.tpu, у результаті’);

writeln(‘чого очистився екран; потім виконалися’);

writeln(‘оператори блоку головної програми, що’);

writeln(‘і надрукували даний текст.’)

end.

Виконавши її, натиснувши Ctrl+F9, переконаємося, що текст буде виведений на чистому екрані.

Питання для контролю:

  1.  Модуль Unit і його використання.
  2.  Створення модуля Unit і його загальна структура.
  3.  Ім'я бібліотечного модуля користувача.
  4.  Интерфейсная секція.
  5.  Секція реалізації.
  6.  Ініціалізаційна частина.
  7.  Підключення модуля користувача до основної програми.
  8.  Компіляція модуля користувача.


Тема 33: Основні принципи ООП. Створення об’єктів. Використання об’єктів

Об'єктно-орієнтоване програмування засноване на «трьох китах» - трьох найважливіших принципах, що додають об'єктам нові властивості. Цими принципами є інкапсуляція, спадкоємство і поліморфізм.   

Інкапсуляція   

Інкапсуляція є об'єднання в єдине ціле даних і алгоритмів обробки цих даних. В рамках ООП дані називаються полями об'єкту, а алгоритми - об'єктними методами.   

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

В результаті заміна або модифікація алгоритмів і даних, інкапсульованих в об'єкт, як правило, не спричиняє за собою наслідків, що погано просліджуються, для програми в цілому (в цілях підвищення захищеності програм в ООП майже не використовуються глобальні змінні).   Іншим важливим наслідком інкапсуляції є легкість обміну об'єктами, перенесення їх з однієї програми в іншу. Можна сказати, що ООП «провокує» розробку бібліотек об'єктів, таких як Turbo Vision.

Спадкоємство   

Спадкоємство є властивість об'єктів породжувати своїх нащадків. Об'єкт-нащадок автоматично успадковує від батька всі поля і методи, може доповнювати об'єкти новими полями і замінювати (перекривати) методи батька або доповнювати їх.   

Принцип спадкоємства вирішує проблему модифікації властивостей об'єкту і додає ООП в цілому виняткову гнучкість.

При роботі з об'єктами програміст зазвичай підбирає об'єкт, найбільш близький по своїх властивостях для вирішення конкретного завдання, і створює одного або декількох нащадків від нього, які «уміють» робити те, що не реалізоване в батьку.   

Послідовне проведення в життя принципу «успадковуй і змінюй» добре узгоджується з поетапним підходом до розробки крупних програмних проектів і багато в чому стимулює такий підхід.   

Поліморфізм   

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

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

У Турбо Паскалі поліморфізм досягається не лише описаним вище механізмом спадкоємства і перекриття методів батька, але і їх віртуалізацією, що дозволяє батьківським методам звертатися до методів нащадків.

Створення об'єктів   

В Турбо Паскалі для створення об'єктів використовуються три зарезервовані слова: object, constructor, destructor до три стандартні директиви: private, public і virtual.   

Зарезервоване слово object використовується для опису об'єкту. Опис об'єкту повинен поміщатися в розділі опису типів:   

type   

Myobject = object   

(Поля об'єкту}   

{Методи об'єкту}     

end ;   

Якщо об'єкт породжується від якого-небудь батька, ім'я батька вказується в круглих дужках відразу за словом object:   

type   

Mydescendantobject = object(Myobject)

 .   .   

end;   

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

Питання для контролю:

  1.  Назвіть основні принципи ООП.
  2.  Поясніть принцип інкапсуляції.
  3.  Поясніть принцип наслідування
  4.  Поясніть принцип поліморфізму
  5.  Створення об’єктів у Турбо Паскалі.


Список літератури