Створення
бібліотек підпрограм у 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>