
- •Алфавіт мови включає в себе:
- •Лексеми мови. Під лексемами розуміють елементарні конструктивні елементи програми, які є неподільними:
- •Оголошення підпрограм: функцій та процедур. Структурне програмування передбачає побудову програм, яка фактично буде послідовністю звертань до підпрограм.
- •Оператор присвоєння присвоює змінній значення виразу, в якості якого може використовуватися і константа, і змінна, і результат обрахування функції, і група операцій. Оператор має вигляд:
- •Складений оператор. Якщо потрібно деяку групу команд інтерпретувати, їх як одну команду, тобто об’єднати їх в певному контексті, то використовують складені оператори.
- •Оператори вводу-виводу. В мові програмування Turbo Pascal ввід-вивід здійснюється насправді не операторами, а стандартними
- •Оператор розгалуження. В ряді випадків алгоритм розв’язку задачі передбачає розгалуження, тобто можливість виконання декількох різних дій в залежності від значення певної логічної умови.
- •Оператори циклу.
- •Програма знаходження суми чисел 1..10.
- •Програма друкування символів ‘a’..’z’.
- •Програма побудови таблиці істинності для and.
- •Скалярні / прості / стандартні типи даних:
- •Скалярні типи користувача:
- •Наприклад
- •4.Структурокані типи даних:
- •1 Діапазон – одновимірний масив;
- •2 Діапазони – двовимірний ( таблиці, матриці);
- •Наприклад
- •5.Комбіновані структури даних.
- •Варіантна частина у записі може бути лише одна і лише в кінці. Службове слово end є спільним для конструкції record і варіантної частини.
- •Приклади задач з масивами
- •Знайти середнє арифметичне додатніх і від’ємних елементів масиву цілих чисел.
- •Стандартні підпрограми обробки рядків
- •Операції над множинами
- •1. Процедури являють собою дію, тому їх можна використовувати в якості окремого оператора в розділі операторів програми.
- •2. Функції являють собою значення певного типу, крім цього вони можуть використовувати деяку дію, але значення їх є головним. Тому функції використовують як окремі оператори у виразах.
- •Параметри-змінні
- •Без типові параметри
- •Наявність умови зупинки, при якій деякому параметру рекурсії передається деяке значення рекурсії.
- •Чітко визначений алгоритм, при обчисленні кожного вищого рівня рекурсії через попередній рівень.
- •Типізовані.
- •Текстові.
- •Безтипові.
- •Процедура зв’язування певної файлової змінної із конкретним файлом на диску
- •Процедура відкриття файлу для читання
- •Процедура відкривання файлу для запису
- •Процедура закривання файлу
- •Процедура примусового очищення внутрішнього буфера обміну
- •Розглянуті раніше встановлюючи та завершальні підпрограми
- •Процедура читання
- •Процедура запису у файл
- •Функція визначення розміру файла у записі
- •Процедура відсікання хвостової частини файлу
- •Процедура читання з текстового файлу
- •Процедура запису
- •1. Процедура для перейменування файлів
- •2. Процедура видалення файлу
- •Xxxx0 адреса
- •35 Квартира з номером 34 у 13 будинку з номером 12.
- •Файли розміщуються в зовнішній пам'яті, а динамічні структури в оперативній.
- •Типізовані файли фактично є файлами прямого доступу, що означає довільний доступ до елементів. В динамічних структурах доступ до елементів виключно послідовний.
- •Здійснюватиметься рух по дереву до крайнього лівого елемента (найменшого).
- •Це значення друкується.
- •Робиться один крок вправо і послідовність 1-3 повторюється відносно нової поточної вершини.
- •Заголовок.
- •Інтерфейс на частина.
- •Розділ реалізації. В реалізації описуються всі компоненти мови, які мають бути невидимі зовні.
- •Процедури управління виконанням програм
- •Функції перетворення типів
- •Процедури і функції для змінних порядкового типу
- •Математичні функції
- •Процедури та функції роботи з рядками
- •Процедури та функції управління динамічною пам’яттю
- •Функції роботи з вказівниками і адресні функції
- •Процедури вводу-виводу і роботи з файлами і каталогами
- •Інші процедури і функції
- •Змінні та константи модуля
- •Змінні модуля crt
- •Процедури і функції модуля crt
- •Перепризначення файлів вводу-виводу
- •Процедури роботи з екраном
- •Процедури і функції управління курсором
- •Процедури роботи з рядками
- •Функції допиту клавіатури
- •Процедури управління кольором
- •Процедури управління вбудованим динаміком і таймером
- •Використання клавіш редагування рядків
- •Використання командних символі
- •Типи драйверів
- •Типи шрифтів
- •Ініціалізація графіки класифікація типів драйверів і відео режимів
- •Ініціалізація і завершення відеорежиму
- •Обробка помилок ініціалізації
- •Процедури роботи з відеорежимами
- •Переключення між текстовим і графічним режимами
- •Побудова зображень на екрані система координат
- •Управління поточним вказівником
- •Графічні вікна
- •Відображення точки на екрані
- •Відображення відрізків прямих ліній
- •Побудова прямокутників
- •Побудова многокутників
- •Побудова дуг, еліпсів і кіл
- •Робота з текстом
- •Відображення рядків
- •Відображення числової інформації
- •Управління параметрами зображення встановлення кольору
- •Встановлення палітри
- •Функції управління операційним середовищем
- •Процедури управління процесами
- •Процедури обслуговування переривань
- •Програми, резидентні в пам'яті
- •Процедури роботи з датою і часом
- •Процедури і функції перевірки стану диску
- •Процедури і функції роботи з файлами
- •Інші процедури і функції
- •Поля даних оголошуються на початку, а методи після них.
- •При оголошенні методів у структурі задаються лише заголовок відповідної підпрограми (подібно до інтерфейсу в модулях).
- •Окремі методи можуть використовувати інші методи цього ж об’єкта, тому вони повинні бути оголошенні в певному порядку.
- •Ini; {ініціалізація графіки}
- •Віртуальним варто оголошувати лише той метод, який:
- •Постановки задачі;
- •Наявними програмними ресурсами;
- •Вимогами по швидкодії, використанням ресурсів еом.
35 Квартира з номером 34 у 13 будинку з номером 12.
Тема: Оголошення та операції над вказівними величинами.
Вказівники оголошуються при допомозі спеціальної операції ^. Ця операція застосовується над деяким базовим типом, при цьому такі вказівники можуть зберігати адреси величин саме цього базового типу.
Хоча всі вказівники - це адреси, проте вказівники на різні базові типи є несумісними.
Наприклад.
TYPE
Pint=^INTEGER;
Pchar=^CHAR;
Pstring=^STRING;
PPint=^Pint;
PPPint=^PPint;
Тут оголошено 5 типів вказівників:
Pint – вказівник цілих чисел; Pchar – вказівник на символи; Pstring – вказівник на рядки; PPint – вказівник на вказівник на цілі; PPPint – вказівник на вказівник на вказівник на цілі.
Хоча всі оголошені типи є вказівниками, проте всі вони не сумісні між собою.
В Pascal є стандартний вказівний тип, який сумісний з будь-яким із вказівників. Тип – pointer.
Змінні у програмі можуть оголошуватися або через раніше названі вказівні типи, або явним чином.
Наприклад.
VAR
Pi1:Pint;
Pi2:^integer;
PPi1:PPint;
PPi2:^Pint;
PPPi1:PPPint;
PPPi2:^PPint;
Кожна з 3-х пар змінних є величинами еквівалентних вказівних типів. Перша змінна в кожній парі оглушена через ідентифікатор вказівного типу, друга – явним чином, через операцію ^. Між змінними кожної пари можна виконувати операції присвоєння.
Значення кожної із змінних – це адреса деякої величини відповідного типу, якщо вказівником не задано значення, то ним буде значення з довільною адресою, що розміщувалася на момент виконання операції.
Для того, щоб отримати адресу деякої змінної базового типу, використовується унарна операція взяття адреси (@).
VAR0000000
i1,i2:integer;
BEGIN
Pi1:=@i1;
PPi1:@Pi1;
PPi2:=@@i1
END;
Змінній Рі1 присвоєна адреса і1; змінній РРі1 присвоєна адреса адреси і1; змінній РРі2 присвоєно теж саме значення, але двократним використанням @.
Якщо потрібно отримати значення деякої величини, адреса якої відома, використовується інша операція – це унарна posfx-на операція і позначається ^.
Ці унарні операції виконуються в напрямі від ідентифікатора змінної. Операція @ виконується з права на ліво, а ^ - з ліва на право.
Для того, щоб застосування операції розіменування вказівника було коректним. Цей вказівник повинен бути попередньо зв’язаний зі змінною оператором @.
Використання вказівників типу pointer дозволяє узгодити поля пам'яті різних типів. Це один із способів перетворення типів.
Взагалі операції присвоєння між вказівниками можливі між однаковими або еквівалентними типами.
VAR
Pi1:Pint;
Pi2:^integer;
PPi1:PPint;
PPi2:^Pint;
Pc1:Pchar;
Pc2:^char
... ... ... ...
Pi1:=PPi1;
Pi1^:=PPi1^; {не можливі}
Pi1:=Pc1;
Pi1^:=Pc!^;
Pi1:=Pi2;
Pi1^:=Pi2^;
PPi1:=PPi2; {можливі}
Pc1:=Pc2;
Pi1:=PPi1^
Як вже відмічалося значення вказівного типу є чотирибайтні числа. формально ці числа розділяються на дві частини по 2 байти: старше, менше слово. Старше слово є адресою початку сегменту; молодше слово – зміщення комірки пам'яті від початку сегмента.
Із усіх можливих значень, які існують, особливе значення має nil, що означає вказівник „в нікуди”. Цей вказівник не співпадає із 1 Мб з жодним і фактично є абстрактним поняттям. Реально в пам'яті такої комірки немає. Значення nil – це не нуль для цілих чи дійсних чисел.
Будь-який із вказівників може набувати значення nil, проте не можна застосовувати операцію розіменування вказівника, оскільки nil не вказує на якусь конкретну ділянку пам'яті.
Тема: Динамічні змінні.
Застосування вказівників дозволило реалізувати особливий вид змінних – динамічних.
На відмінну від іншого виду змінних (статичні), які існують протягом всього часу виконання програми, динамічні змінні можуть створюватися і знищуватися в будь-який момент програми спеціальними програмами.
Статичні змінні - це всі змінні, що оголошені в розділі var незалежно від типу. Ці змінні розміщуються в спеціальному сегменті пам'яті, що називають статичною пам’яттю або програмним стеком (не більше 64 Кб). Ці змінні слідують в порядку оголошення у програмі. Вони з'являються на початку виконання програми і стек звільняється при завершені програми.
Враховуючи, що стек не перевищує 1 сегменту пам'яті, а отже кількість статичних змінних буде обмежена.
Динамічні змінні розміщуються в особливій частині оперативної пам'яті, що називається динамічною пам’яттю, або Heap-областю, або кучею. Під кучу відводиться вся вільна на момент виконання програми пам'ять. Враховуючи, що перших 360 Кб базової пам'яті займає ОП, то максимальний розмір буде 640 Кб.
Реально всі програми, які виконуються паралельно із Pascal-програмою теж частково використовують оперативну пам'ять.
Всі динамічні змінні створюються виключно спеціальними командами, так само вони і знищуються.
Для створення і знищення динамічних змінних є три групи підпрограм:
NEW ( var p:point); DISPOSE(var p:pointer).
MARK (var p:pointer); RELASE (var p:pointer).
GETMEM (var p:pointer; size:longint); FREEMEM (var p:pointer; size:longint).
Перші процедури в кожній групі створюють динамічні змінні; другі – знищують. Використання кожної із груп процедур визначається потребами програми, оскільки результати їх роботи відмінні.
При створенні динамічних змінних процедурою New, в якості фактичного параметра використовується статична змінна вказівного типу.
VAR
Pi1:Pint;
Ppi1:PPint;
Pc:Pchar;
Ps:^string;
BEGIN
New(Pi1);
New(PPi1);
New(Pc);
New(Ps);
END.
Тут створюється 4 динамічних змінних, на які є статичні вказівники. Перша динамічна змінна матиме тип integer, друга – вказівний тип на integer, третя – тип char, четверта – тип string.
Динамічні змінні розміщуються у пам'яті не неперервним чином, а, починаючи з кожного нового 8 б блоку. Таким чиною створення динамічних змінних малих розмірів є малоефективним, оскільки з користю використовується 1\8, 1\4.
Якщо динамічна змінна створена процедурою New, то знищення можна провести лише відповідною Dispose. Відповідна ділянка кучі звільнюється, а параметр вказівника втрачає своє значення.
При звільненні частини кучі процедурою Dispose з'являються вільні фрагменти пам'яті можливо достатньо великого розміру. Чи будуть при новому створені динамічні змінні розміщуватися в звільнених ділянках? При новому створені, динамічні змінні розміщуються, починаючи з першого 8-мибайтного блоку після останньої динамічної змінної в мові Рascal завжди рівне адресі початку першого 8-мибайтного блоку після останньої динамічної змінної в кучі: Heap ptr.
Всі новостворені динамічні змінні розміщуються, починаючи з адреси Heap ptr. Після кожного нового створення Heap ptr збільшує своє значення.
Друга група підпрограм для створення динамічних змінних оперує лише з динамічними змінними типу pointer і розміром цієї змінної 4 байти.
В якості інформаційної комірки використовувати її малоефективно.
При створені динамічних змінних процедурою Mark(р), її параметр типу pointer отримує значення вказівника Heap ptr. Таким чином змінна р фіксує стан динамічної пам'яті процедурою Mark.
Після фіксації стану, в ній можуть бути створені або знищенні динамічні змінні попередніми процедурами, при цьому вказівник Heap ptr буде отримувати нове значення. Повернутися до зафіксованого раніше процедурою Mark значення Heap ptr можна процедурою Release(p) з цим самим значенням. При цьому не відбувається знищення чи добавлення даних до зафіксованого значення.
Всі динамічні змінні, що знаходяться вище цього значення будуть вважатися знищеними. Виникає питання: що буде в наступній ситуації.
New(p1);
New(p2);
Mark(p);
Dispose(p1);
Dispose(p2);
Release(p);
Така ситуація не відновлює дані, хоча Heap ptr вказує на вершину раніше зайнятої кучі. Утворюються пустоти, в яких не вдасться розмістити нові динамічні змінні.
При розміщенні динамічних змінних у пам'яті, потрібно враховувати, що неможливість чергової операції створення динамічної змінної із-за відсутності місця в кучі, призводить до зупинки програми, тому потрібно контролювати стан динамічної пам'яті на наявності вільного простору. Для цього Pascal має стандартні функції без параметрів.
MemAvail:longint;
MaxAvail:longint;
MemAvail повертає своїм значенням загальний розмір вільної пам'яті в перерахунку на 8-мибайтні блоки. Цей розмір видається в байтах.
MaxAvail повертає своїм значенням розмір максимальної неперервної вільної ділянки в кучі в перерахунку на 8-мибайтні блоки. Таким чином при операціях багатократного створення динамічних змінних варто користуватися наступною перевіркою
if MaxAvail>=sizeof(<базовий тип>) then New(…)
else writeln(‘немає місця’);
Тема: Динамічні структури даних.
Використання вказівники та динамічних змінних дозволяє будувати нові структури даних, які називаються динамічними. Вони розміщуються в динамічній частині пам'яті і можуть як завгодно змінювати свій розмір, тобто кількість елементів, таким чином дечим подібні до типізованих файлів, які теж можуть змінювати свій розмір. Проте є деякі принципові відмінності: