Створення
бібліотек підпрограм у Turbo Pascal  h2>
 Стандартний
мова Pascal не має коштів розробки та підтримки бібліотек
програміста (на відміну, скажімо, від мови Fortran та інших мов
програмування високого рівня), які компілюються окремо і в
надалі можуть бути використані як самим розробником, так і іншими. Якщо
програміст має досить великі напрацювання, і ті або інші підпрограми можуть
бути використані при написанні нових додатків, то доводиться ці
підпрограми цілком включати в новий текст.  p>
 У Turbo Pascal
це обмеження долається за рахунок, по-перше, введення зовнішніх процедур,
по-друге, розробки та використання модулів. У даній публікації на
прикладах розглянемо роботу з тими і іншими програмними одиницями.  p>
 Почнемо з
зовнішніх підпрограм.  p>
 Такий механізм
передбачає, що вихідний текст кожної процедури або функції зберігається в
окремому файлі і при необхідності за допомогою спеціальної директиви компілятора
включається в текст створюваної програми.  p>
 Покажемо це на
прикладі завдань цілочисельний арифметики, де аргументи, результати та
проміжні величини є цілими (Integer, Word, LongInt і т.д.). Ось
кілька таких завдань.  p>
 1. Дано
натуральне число n. Знайти суму перших та останньої цифри цього числа.  P>
 2. Дано
натуральне число n. Переставити місцями першу і останню цифри цього числа.  P>
 3. Дано
натуральне число n. Дописати до нього цифру k в кінець і на початок (якщо це можливо,
тобто результат не вийде за діапазон допустимих значень), або повідомити про
неможливості виконання операції.  p>
 4. Знайти
найбільшу цифру в запису даного натурального числа.  p>
 5. Дано
натуральне число n. Переставити його цифри так, щоб утворилося максимальне
число, записане тими ж цифрами.  p>
 При вирішенні
кожної з цих завдань може бути використана функція, що повертає кількість
цифр у запису натурального числа.  p>
 Ось можливий
варіант такої функції:  p>
 Function Digits (N: LongInt): Byte;  p>
 Var Kol: Byte;  p>
 Begin  p>
 Kol: = 0;  p>
 While N
<> 0 Do Begin Kol: = Kol + 1; N: = N Div 10 End;  p>
 Digits: =
Kol  p>
 End;  p>
 Збережемо цей
текст у файлі з розширенням. inc (це розширення зовнішніх підпрограм у Turbo
Pascal), наприклад, digits.inc.  P>
 Ще необхідна
функція зведення натурального числа в натуральну ступінь.  p>
 Function Power (A, N: LongInt): LongInt; (файл power.inc)  p>
 Var I, St: LongInt;  p>
 Begin  p>
 St: = 1;  p>
 For I: = 1
To N Do St: = St * A;  p>
 Power: = St  p>
 End;  p>
 Спробуємо
використовувати функції при вирішенні завдання номер один.  p>
 Program Example1;  p>
 Var N, S: LongInt;  p>
 ($ I digits.inc) (підключаємо зовнішню функцію digits.inc, який повертає
кількість цифр у записі числа)  p>
 ($ I power.inc)
(зовнішня функція, що виконує зведення числа A до степеня N)  p>
 Begin  p>
 Write ( 'Введіть натуральне число:'); p>
 ReadLn (N);  p>
 (для
визначення останньої цифри числа N беремо залишок від ділення цього числа на 10,
а для визначення першого ділимо N на 10 в ступені на одиницю меншу, ніж
кількість цифр у записі числа
(розрядів нумерація починається з 0))  p>
 S: = N Mod 10 + N Div Power (10,
Digits (N) - 1);  p>
 WriteLn ( 'Бажаєма сума:', S)  p>
 End.  p>
 Зовнішні
процедури створюються і впроваджуються в використовують їх програми аналогічно
функцій, і ми не будемо детально на цьому зупинятися.  p>
 Далі мова
піде про модулях: їхній структурі, розробки, компіляції та використанні.  p>
 Модуль - це
набір ресурсів (функцій, процедур, констант, змінних, типів і т.д.),
розробляються і зберігаються незалежно від використовують їх програм. На відміну від
зовнішніх підпрограм модуль може містити достатньо великий набір процедур і
функцій, а також інших ресурсів для розробки програм. Зазвичай кожен модуль
містить логічно пов'язані між собою програмні ресурси.  p>
 В основі ідеї
модульності лежать принципи структурного програмування. Існують
стандартні модулі Turbo Pascal, які зазвичай описуються в літературі по
даного мови.  p>
 Модуль має
наступну структуру:  p>
 Unit <ім'я
модуля>; (заголовок модуля)  p>
 Interface  p>
 (інтерфейсна частину)  p>
 Implementation  p>
 (розділ реалізації)  p>
 Begin  p>
 (розділ ініціалізації модуля)  p>
 End.  p>
 Після
службового слова Unit записується ім'я модуля, яке (для зручності подальших
дій) має збігатися з ім'ям файлу, що містить даний модуль. Тому
(як прийнято в MS DOS) ім'я не повинно бути більше ніж 8 символів.  p>
 У розділі
Interface оголошуються всі ресурси, які будуть надалі доступні
програмісту при підключенні модуля. Для підпрограм тут вказується лише
повний заголовок.  p>
 У розділі
Implementation реалізуються всі підпрограми, які були раніше оголошені.
Крім того, тут можуть міститися свої константи, змінні, типи,
підпрограми і т.д., які носять допоміжний характер і використовуються для
написання основних підпрограм. На відміну від ресурсів, оголошених у роздiлi
Interface, все, що додатково оголошується в Implementation, вже не буде
доступно при підключенні модуля. При написанні основних підпрограм достатньо
вказати їх ім'я (тобто не потрібно повністю переписувати весь заголовок), а потім
записати тіло підпрограми.  p>
 Нарешті, розділ
ініціалізації (який часто відсутня) містить оператори, які повинні
бути виконані відразу ж після запуску програми, що використовує модуль.  p>
 Наведемо приклад
розробки і використання модуля. Оскільки розглянута нижче завдання
досить елементарна, обмежимося лістингом програми з докладними
коментарями.  p>
 Завдання.
Реалізувати у вигляді модуля набір підпрограм для виконання наступних операцій
над звичайними дробами виду P/Q (P - ціле, Q - натуральне): 1) складання;
2) віднімання; 3) множення; 4) розподіл; 5) скорочення дробу; 6) зведення
дробу до степеня N (N - натуральне); 7) функції, що реалізують операції відносини
(так само, не дорівнює, більше або дорівнює, менше або дорівнює, більше, менше).  p>
 Дріб
представити таким типом:  p>
 Type Frac = Record  p>
 P: Integer;  p>
 Q: 1 .. High (LongInt)  p>
 End;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Дано масив A
- Масив звичайних дробів. Знайти суму всіх дробів, відповідь представити у вигляді
несократімой дробу. Обчислити середнє арифметичне всіх дробів, відповідь
представити у вигляді несократімой дробу.  p>
 2. Дано масив A
- Масив звичайних дробів. Відсортувати його в порядку зростання.  P>
 Unit Droby;  p>
 Interface  p>
 Type  p>
 Natur = 1 .. High (LongInt);  p>
 Frac = Record  p>
 P: LongInt; (Чисельник дробу)  p>
 Q: Natur (Чисельник дробу)  p>
 End;  p>
 Procedure Sokr (Var A: Frac);  p>
 Procedure Summa (A, B: Frac; Var C: Frac);  p>
 Procedure Raznost (A, B: Frac; Var C: Frac);  p>
 Procedure Proizvedenie (A, B: Frac; Var C: Frac);  p>
 Procedure Chastnoe (A, B: Frac; Var C: Frac);  p>
 Procedure Stepen (A: Frac; N: Natur; Var C: Frac);  p>
 Function Menshe (A, B: Frac): Boolean;  p>
 Function Bolshe (A, B: Frac): Boolean;  p>
 Function Ravno (A, B: Frac): Boolean;  p>
 Function MensheRavno (A, B: Frac): Boolean;  p>
 Function BolsheRavno (A, B: Frac): Boolean;  p>
 Function NeRavno (A, B: Frac): Boolean;  p>
 (Розділ
реалізації модуля)  p>
 Implementation  p>
 (Найбільший
спільний дільник двох чисел - допоміжна функція, що раніше не оголошена)  p>
 Function NodEvklid (A, B: Natur): Natur;  p>
 Begin  p>
 While A
<> B Do  p>
 If A> B
Then  p>
 If A Mod B <> 0 Then A: = A Mod B
Else A: = B  p>
 Else  p>
 If B Mod A <> 0 Then B: = B Mod A
Else B: = A;  p>
 NodEvklid
: = A  p>
 End;  p>
 Procedure Sokr; (Скорочення дробу)  p>
 Var M, N: Natur;  p>
 Begin  p>
 If A.P
<> 0 Then  p>
 Begin  p>
 If A.P <0
Then M: = Abs (A.P)  p>
 Else M: = AP; (Поєднання типів, тому що A.P --
LongInt)  p>
 N: =
NodEvklid (M, A.Q); A.P: = A.P Div N; A.Q
: = A.Q Div N  p>
 End  p>
 End;  p>
 Procedure Summa; (Сума дробів)  p>
 Begin  p>
 (Чисельник дробу)
C.Q: = (A.Q * B.Q) Div NodEvklid (A.Q, B.Q);  p>
 (Чисельник дробу)
C.P: = A.P * C.Q Div A.Q + B.P * C.Q Div B.Q;  p>
 Sokr (C)  p>
 End;  p>
 Procedure Raznost; (Різниця дробів)  p>
 Begin  p>
 (Чисельник дробу) CQ: = (AQ * BQ) Div NodEvklid (AQ,
B.Q);  p>
 (Чисельник дробу)
C.P: = A.P * C.Q Div A.Q - B.P * C.Q Div B.Q;  p>
 Sokr (C)  p>
 End;  p>
 Procedure Proizvedenie;  p>
 Begin  p>
 (Чисельник дробу) CQ: = AQ * BQ;  p>
 (Чисельник дробу) CP: = AP * BP;  p>
 Sokr (C)  p>
 End;  p>
 Procedure Chastnoe;  p>
 Begin  p>
 (Чисельник дробу)
C.Q: = A.Q * B.P;  p>
 (Чисельник дробу)
C.P: = A.P * B.Q;  p>
 Sokr (C)  p>
 End;  p>
 Procedure Stepen; (Ступінь)  p>
 Var I: Natur;  p>
 Begin  p>
 C.Q: = 1;
C.P: = 1; Sokr (A);  p>
 For I: = 1
To N Do Proizvedenie (A, C, C)  p>
 End;  p>
 Function Menshe;  p>
 Begin Menshe: = AP * BQ 
 Function Bolshe;  p>
 Begin Bolshe
: = A.P * B.Q> A.Q * B.P End;  p>
 Function Ravno;  p>
 Begin Ravno: = A.P * B.Q = A.Q * B.P End;  p>
 Function BolsheRavno;  p>
 Begin BolsheRavno: = Bolshe (A, B) Or Ravno (A, B) End;  p>
 Function MensheRavno;  p>
 Begin MensheRavno: = Menshe (A, B) Or Ravno (A, B) End;  p>
 Function NeRavno;  p>
 Begin NeRavno
: = Not Ravno (A, B) End;  p>
 (Розділ
ініціалізації модуля)  p>
 Begin  p>
 End.  p>
 Дамо деякі
рекомендації з розробки модулів:  p>
 1)
спроектувати модуль, тобто виділити основні та допоміжні підпрограми,
інші ресурси;  p>
 2) кожну
підпрограму доцільно налагодити окремо, після чого «вклеїти» в текст
модуля.  p>
 Збережемо текст
розробленої програми у файлі DROBY.PAS і откомпіліруем наш модуль. Для цього
можна скористатися зовнішнім компілятором, що поставляються разом з Turbo Pascal.
Команда буде виглядати так: TPC DROBY.PAS. Якщо в тексті немає синтаксичних
помилок, отримаємо файл DROBY.TPU, інакше буде відповідне повідомлення з
зазначенням рядка, що містить помилку. Інший спосіб компіляції модуля - у середовищі
програмування Turbo Pascal вибрати у пункті меню Run підпункти Make або
Build (при цьому повинна бути включена компіляція на диск).  P>
 Тепер можна
підключити модуль до програми, де планується його використання.  p>
 Для прикладу
вирішимо завдання підсумовування масиву дробів.  p>
 Program Sum;  p>
 Uses Droby;  p>
 Var A: Array [1 .. 100] Of Frac;  p>
 I, N:
Integer;  p>
 S: Frac;  p>
 Begin  p>
 Write ( 'Введіть кількість елементів
масиву:'); p>
 ReadLn (N);  p>
 SP: = 0; SQ: = 1; (Спочатку сума
дорівнює нулю)  p>
 For I: = 1 To N Do (Вводимо та підсумовуємо дробу)  p>
 Begin  p>
 Write ( 'Введіть чисельник', I, '-й дробу:');
ReadLn (A [I]. P);  p>
 Write ( 'Введіть знаменник', I, '-й дробу:');
ReadLn (A [I]. Q);  p>
 Summa (A [I], S,
S);  p>
 End;  p>
 WriteLn ( 'Відповідь:', S.P, '/',
S.Q)  p>
 End.  p>
 Другу задачу
пропонуємо вирішити читачеві самостійно.  p>
 Як видно з
приклад, для підключення модуля використовується службове слово USES, після чого
вказується ім'я модуля і відбувається це відразу ж після заголовка програми.
Якщо необхідно підключити декілька модулів, вони перераховуються через кому.  P>
 При
використанні ресурсів модуля зовсім не потрібно знати, як працюють його
підпрограми. Достатньо володіти інформацією, як виглядають їх заголовки і
яку дію ці підпрограми виконують. За таким принципом здійснюється
робота з усіма стандартними модулями. Тому, якщо програміст розробляє
модулі не тільки для особистого користування, йому необхідно зробити повне
опис всіх доступних при підключенні ресурсів. У такому випадку можлива повноцінна
робота з таким продуктом.  p>
 Ще кілька
слів про видимості об'єктів модуля. Якщо в програмі, що використовує модуль,
є ідентифікатори, що збігаються з точністю до символу з ідентифікаторами
модуля, то вони «перекривають» відповідні ресурси модуля. Тим не менше, навіть
в такій ситуації доступ до цих ресурсів модуля може бути отриманий таким
так: <ім'я модуля>. <ім'я ресурсу>.  p>
 На закінчення
наведемо набір завдань, що дозволяють отримати певні навички в розробці
модулів.  p>
 I. Реалізувати
у вигляді модуля набір підпрограм для виконання наступних операцій над
комплексними числами: 1) складання; 2) віднімання; 3) множення; 4) розподіл; 5)
обчислення модуля комплексного числа; 6) зведення комплексного числа в
ступінь n (n - натуральне).  p>
 Комплексне число
представити таким типом:  p>
 Type Complex = Record  p>
 R, M: Real;
(дійсна і уявна частина числа)  p>
 End;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Дано масив A
- Масив комплексних чисел. Отримати масив C, елементами якого будуть модулі
сум поруч стоять комплексних чисел.  p>
 2. Дан масив
A [M] - масив комплексних чисел. Отримати матрицю B [N, M], кожен рядок
якої виходить зведенням до степеня, що дорівнює номеру цього рядка,
відповідних елементів даного масиву A.  p>
 II. Реалізувати
у вигляді модуля набір підпрограм для виконання наступних операцій з квадратними
матрицями: 1) складання двох матриць; 2) множення однієї матриці на іншу; 3)
знаходження транспонований матриці; 4) обчислення визначника матриці.  p>
 Матрицю описати
наступним чином:  p>
 Const NMax = 10;  p>
 Type
Matrica = Array [1 .. NMax, 1 .. Nmax] Of Real;  p>
 Використовуючи цей
модуль, вирішити наступні завдання:  p>
 1. Вирішити
систему лінійних рівнянь N-го порядку (2 <= N <= 10) методом Крамера.  p>
 2. Задано масив
величин типу Matrica. Відсортувати цей масив в порядку зростання значень
визначників матриць.  p>
 III.
Реалізувати у вигляді модуля набір підпрограм для виконання наступних операцій
над векторами на площині: 1) складання; 2) віднімання; 3) скалярний множення
векторів; 4) множення вектора на число; 5) довжина вектора.  p>
 Вектор
представити таким типом:  p>
 Type Vector = Record X, Y: Real End;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Дано масив A
- Масив векторів. Відсортувати його в порядку зменшення довжин векторів.  P>
 2. За допомогою
датчика випадкових чисел згенерувати 2N цілих чисел. N пар цих чисел задають N
точок координатної площини. Вивести номери трійки точок, які є
координатами вершин трикутника з найбільшим кутом.  p>
 IV. Реалізувати
у вигляді модуля набір підпрограм для виконання наступних операцій над
натуральними числами в P-ічной системі числення (2 <= P <= 9): 1) складання;
2) віднімання; 3) множення; 4) розподіл; 5) переведення з десяткової системи
числення в P-ічную; 6) переклад з P-ічной системи числення в десяткову; 7)
логічна функція перевірки правильності запису числа в P-ічной системі
числення; 8) функції, що реалізують операції відносини (так само, не дорівнює, більше
або дорівнює, менше або дорівнює, більше, менше).  p>
 P-ічное число
представити таким типом:  p>
 Type Chislo = Array [1 .. 64] Of 0 .. 8;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Звести
число до степеня (підстава і показник ступеня записані в P-ічной системі
числення). Відповідь видати в P-ічной і десяткового системах числення.  P>
 2. Дано масив A
- Масив чисел, записаних в P-ічной системі числення. Відсортувати його в
порядку убування. Відповідь видати в P-ічной і десяткового системах числення.  P>
 V. Реалізувати
у вигляді модуля набір підпрограм для виконання наступних операцій над
натуральними числами в шістнадцятковій системі числення: 1) складання; 2)
віднімання; 3) множення; 4) розподіл; 5) переведення із двійкової системи числення в
шістнадцяткову; 6) переклад з шістнадцятковій системи числення в
десяткову; 7) функція перевірки правильності запису числа в шістнадцятковій
системі числення; 8) функції, що реалізують операції відносини (так само, не одно,
більше або дорівнює, менше або дорівнює, більше, менше).  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Звести
число до степеня (підстава і показник ступеня записані в шістнадцятковій
системі числення). Відповідь видати в шістнадцятковій і десяткового системах
числення.  p>
 2. Дано масив A
- Масив чисел, записаних в шістнадцятковій системі числення. Відсортувати
його в порядку убування. Відповідь видати в шістнадцятковій і десяткового системах
числення.  p>
 VI. Визначимо
граф як набір точок, деякі з яких з'єднані відрізками, подграф - граф,
підмножина даного графа. Реалізувати у вигляді модуля набір підпрограм,
визначають: 1) число точок у графі; 2) число відрізків у графі; 3) число
ізольованих подграфов в графі (подграфов, не з'єднаних відрізками);
4) діаметр графа - довжину максимальної незамкненою лінії в графі (довжина кожного
ланки - одиниця); 5) граф - об'єднання двох графів; 6) подграф - перетин
двох графів; 7) подграф - доповнення даного графа до повного (графа з тим же
кількістю вершин, що і в заданому, і з лініями між будь-якими двома
вершинами); 8) кількість відрізків, що виходять з кожної вершини графа; 9) при
запуску повинні ініціалізувати змінні: Full_Graph - повний граф з числом
вершин NumberOfVertix, Null_Graph - граф без відрізків з числом вершин
NumberOfVertix.  P>
 Граф
представити як об'єкт  p>
 Const NumberOfVertix = 50;  p>
 Type Graph = Array [1 .. NumberOfVertix,
1 .. NumberOfVertix] Of Boolean;  p>
 Використовуючи
модуль, вирішити завдання: знайти усі правильні графи з N вершин (граф правильний,
якщо з усіх вершин виходить рівну кількість відрізків).  p>
 VII.
Реалізувати у вигляді модуля набір підпрограм для роботи з довгими цілими
числами (числами, що виходять за діапазон допустимих значень будь-якого цілого
типу): 1) складання; 2) віднімання; 3) множення; 4) знаходження приватного та залишку
від ділення одного числа на інше; 5) функції, що реалізують операції відносини
(так само, не дорівнює, більше або дорівнює, менше або дорівнює, більше, менше).  p>
 Довге число
представити слід?? ющім типом:  p>
 Type
Tsifra = 0 .. 9; Chislo = Array [1 .. 1000] Of Tsifra;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Звести
число до степеня (підстава і показник ступеня - довгі числа).  p>
 2. Дан масив
довгих чисел. Упорядкувати цей масив в порядку убування.  P>
 VIII.
Реалізувати у вигляді модуля набір підпрограм для виконання операцій з
многочленами від однієї змінної (перший многочлен ступеня m, друге - ступеня
n): 1) складання; 2) віднімання; 3) множення; 4) поділ із залишком; 5) операції
відносини (так само, не дорівнює); 6) зведення в натуральну ступінь k одного з
многочленів; 7) обчислення похідної від многочлена; 8) обчислення значення в
точці x0.  p>
 Многочлен
представити таким типом:  p>
 Type
Mnogochlen = Array [1 .. 500] Of Integer;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Знайти
найбільший спільний дільник многочленів P (x) і Q (x).  p>
 2. Обчислити:
Ps (x)-Qr (x) (s, r - натуральні).  P>
 IX *.
Реалізувати у вигляді модуля набір підпрограм для роботи з довгими
дійсними числами (числами, що виходять за діапазон допустимих значень
дійсних будь-якого типу або не представлених в пам'яті ЕОМ): 1) складання; 2)
віднімання; 3) множення; 4) знаходження приватного від ділення одного числа на
інше із заданою кількістю знаків після коми; 5) функції, що реалізують
операції відносини (так само, не дорівнює, більше або дорівнює, менше або рівне,
більше, менше); 6) тригонометричні функції, де аргументом і значеннями
є довгі дійсні числа (вказівка: використовувати розкладання відповідної
функції в ряд).  p>
 Довге
дійсне число представити таким типом:  p>
 Type Tsifra = 0 .. 9; Chislo = Array
[1 .. 1000] Of Tsifra;  p>
LongReal = Record  p>
Znak: 0 .. 1; (0 - "плюс",
1 - "мінус")  p>
Ts, Dr: Chislo (ціла
і дробова частини)  p>
 End;  p>
 Використовуючи цей
модуль, вирішити завдання:  p>
 1. Звести
число до степеня (підстава - довге дійсне, показник ступеня --
довге ціле число).  p>
 2. Дан масив
довгих дійсних чисел. Упорядкувати цей масив в порядку зростання.  P>
 Список
літератури  h2>
 Для підготовки
даної роботи були використані матеріали з сайту http://www.comp-science.narod.ru/
 p>