Создание библиотек подпрограмм в Turbo Pascal (46195)

Посмотреть архив целиком

Создание библиотек подпрограмм в Turbo Pascal

Стандартный язык Pascal не располагает средствами разработки и поддержки библиотек программиста (в отличие, скажем, от языка Fortran и других языков программирования высокого уровня), которые компилируются отдельно и в дальнейшем могут быть использованы как самим разработчиком, так и другими. Если программист имеет достаточно большие наработки, и те или иные подпрограммы могут быть использованы при написании новых приложений, то приходится эти подпрограммы целиком включать в новый текст.

В Turbo Pascal это ограничение преодолевается за счет, во-первых, введения внешних процедур, во-вторых, разработки и использования модулей. В настоящей публикации на примерах рассмотрим работу с теми и другими программными единицами.

Начнем с внешних подпрограмм.

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

Покажем это на примере задач целочисленной арифметики, где аргументы, результаты и промежуточные величины являются целыми (Integer, Word, LongInt и т.д.). Вот несколько таких задач.

1. Дано натуральное число n. Найти сумму первой и последней цифры этого числа.

2. Дано натуральное число n. Переставить местами первую и последнюю цифры этого числа.

3. Дано натуральное число n. Дописать к нему цифру k в конец и в начало (если это возможно, т.е. результат не выйдет за диапазон допустимых значений), или сообщить о невозможности выполнения операции.

4. Найти наибольшую цифру в записи данного натурального числа.

5. Дано натуральное число n. Переставить его цифры так, чтобы образовалось максимальное число, записанное теми же цифрами.

При решении каждой из этих задач может быть использована функция, возвращающая количество цифр в записи натурального числа.

Вот возможный вариант такой функции:

Function Digits(N : LongInt) : Byte;

Var Kol : Byte;

Begin

Kol := 0;

While N <> 0 Do Begin Kol := Kol + 1; N := N Div 10 End;

Digits := Kol

End;

Сохраним этот текст в файле с расширением .inc (это расширение внешних подпрограмм в Turbo Pascal), например, digits.inc.

Еще необходима функция возведения натурального числа в натуральную степень.

Function Power(A, N : LongInt) : LongInt; {файл power.inc}

Var I, St : LongInt;

Begin

St := 1;

For I := 1 To N Do St := St * A;

Power := St

End;

Попробуем использовать функции при решении задачи номер один.

Program Example1;

Var N, S : LongInt;

{$I digits.inc} {подключаем внешнюю функцию digits.inc, возвращающую количество цифр в записи числа}

{$I power.inc} {внешняя функция, выполняющая возведение числа A в степень N}

Begin

Write('Введите натуральное число: ');

ReadLn(N);

{для определения последней цифры числа N берем остаток от деления этого числа на 10, а для определения первой делим N на 10 в степени на единицу меньшую, чем количество цифр в записи числа (нумерация разрядов начинается с 0)}

S := N Mod 10 + N Div Power(10, Digits(N) - 1);

WriteLn('Искомая сумма: ', S)

End.

Внешние процедуры создаются и внедряются в использующие их программы аналогично функциям, и мы не будем подробно на этом останавливаться.

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

Модуль — это набор ресурсов (функций, процедур, констант, переменных, типов и т.д.), разрабатываемых и хранимых независимо от использующих их программ. В отличие от внешних подпрограмм модуль может содержать достаточно большой набор процедур и функций, а также других ресурсов для разработки программ. Обычно каждый модуль содержит логически связанные между собой программные ресурсы.

В основе идеи модульности лежат принципы структурного программирования. Существуют стандартные модули Turbo Pascal, которые обычно описываются в литературе по данному языку.

Модуль имеет следующую структуру:

Unit <имя модуля>; {заголовок модуля}

Interface

{интерфейсная часть}

Implementation

{раздел реализации}

Begin

{раздел инициализации модуля}

End.

После служебного слова Unit записывается имя модуля, которое (для удобства дальнейших действий) должно совпадать с именем файла, содержащего данный модуль. Поэтому (как принято в MS DOS) имя не должно содержать более 8 символов.

В разделе Interface объявляются все ресурсы, которые будут в дальнейшем доступны программисту при подключении модуля. Для подпрограмм здесь указывается лишь полный заголовок.

В разделе Implementation реализуются все подпрограммы, которые были ранее объявлены. Кроме того, здесь могут содержаться свои константы, переменные, типы, подпрограммы и т.д., которые носят вспомогательный характер и используются для написания основных подпрограмм. В отличие от ресурсов, объявленных в разделе Interface, все, что дополнительно объявляется в Implementation, уже не будет доступно при подключении модуля. При написании основных подпрограмм достаточно указать их имя (т.е. не нужно полностью переписывать весь заголовок), а затем записать тело подпрограммы.

Наконец, раздел инициализации (который часто отсутствует) содержит операторы, которые должны быть выполнены сразу же после запуска программы, использующей модуль.

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

Задача. Реализовать в виде модуля набор подпрограмм для выполнения следующих операций над обыкновенными дробями вида P/Q (P — целое, Q — натуральное): 1) сложение; 2) вычитание; 3) умножение; 4) деление; 5) сокращение дроби; 6) возведение дроби в степень N (N — натуральное); 7) функции, реализующие операции отношения (равно, не равно, больше или равно, меньше или равно, больше, меньше).

Дробь представить следующим типом:

Type Frac = Record

P : Integer;

Q : 1.. High(LongInt)

End;

Используя этот модуль, решить задачи:

1. Дан массив A — массив обыкновенных дробей. Найти сумму всех дробей, ответ представить в виде несократимой дроби. Вычислить среднее арифметическое всех дробей, ответ представить в виде несократимой дроби.

2. Дан массив A — массив обыкновенных дробей. Отсортировать его в порядке возрастания.

Unit Droby;

Interface

Type

Natur = 1..High(LongInt);

Frac = Record

P : LongInt; {Числитель дроби}

Q : Natur {Знаменатель дроби}

End;

Procedure Sokr(Var A : Frac);

Procedure Summa(A, B : Frac; Var C : Frac);

Procedure Raznost(A, B : Frac; Var C : Frac);

Procedure Proizvedenie(A, B : Frac; Var C : Frac);

Procedure Chastnoe(A, B : Frac; Var C : Frac);

Procedure Stepen(A : Frac; N : Natur; Var C : Frac);

Function Menshe(A, B : Frac) : Boolean;

Function Bolshe(A, B : Frac) : Boolean;

Function Ravno(A, B : Frac) : Boolean;

Function MensheRavno(A, B : Frac) : Boolean;

Function BolsheRavno(A, B : Frac) : Boolean;

Function NeRavno(A, B : Frac) : Boolean;

{Раздел реализации модуля}

Implementation

{Наибольший общий делитель двух чисел - вспомогательная функция, ранее не объявленная}

Function NodEvklid(A, B : Natur) : Natur;

Begin

While A <> B Do

If A > B Then

If A Mod B <> 0 Then A := A Mod B Else A := B

Else

If B Mod A <> 0 Then B := B Mod A Else B := A;

NodEvklid := A

End;

Procedure Sokr; {Сокращение дроби}

Var M, N : Natur;

Begin

If A.P <> 0 Then

Begin

If A.P < 0 Then M := Abs(A.P)

Else M := A.P; {Совмещение типов, т.к. A.P - LongInt}

N := NodEvklid(M, A.Q); A.P := A.P Div N; A.Q := A.Q Div N

End

End;

Procedure Summa; {Сумма дробей}

Begin

{Знаменатель дроби} C.Q := (A.Q * B.Q) Div NodEvklid(A.Q, B.Q);

{Числитель дроби} C.P := A.P * C.Q Div A.Q + B.P * C.Q Div B.Q;

Sokr(C)

End;

Procedure Raznost; {Разность дробей}

Begin

{Знаменатель дроби} C.Q := (A.Q * B.Q) Div NodEvklid(A.Q, B.Q);

{Числитель дроби} C.P := A.P * C.Q Div A.Q - B.P * C.Q Div B.Q;

Sokr(C)

End;

Procedure Proizvedenie;

Begin

{Знаменатель дроби} C.Q := A.Q * B.Q;

{Числитель дроби} C.P := A.P * B.P;

Sokr(C)

End;

Procedure Chastnoe;

Begin

{Знаменатель дроби} C.Q := A.Q * B.P;

{Числитель дроби} C.P := A.P * B.Q;

Sokr(C)

End;

Procedure Stepen; {Степень}

Var I : Natur;

Begin

C.Q := 1; C.P := 1; Sokr(A);

For I := 1 To N Do Proizvedenie(A, C, C)

End;

Function Menshe;

Begin Menshe := A.P * B.Q < A.Q * B.P End;

Function Bolshe;

Begin Bolshe := A.P * B.Q > A.Q * B.P End;

Function Ravno;

Begin Ravno := A.P * B.Q = A.Q * B.P End;

Function BolsheRavno;

Begin BolsheRavno := Bolshe(A, B) Or Ravno(A, B) End;

Function MensheRavno;

Begin MensheRavno := Menshe(A, B) Or Ravno(A, B) End;

Function NeRavno;

Begin NeRavno := Not Ravno(A, B) End;

{Раздел инициализации модуля}

Begin

End.

Дадим некоторые рекомендации по разработке модулей:

1) спроектировать модуль, т.е. выделить основные и вспомогательные подпрограммы, другие ресурсы;

2) каждую подпрограмму целесообразно отладить отдельно, после чего «вклеить» в текст модуля.

Сохраним текст разработанной программы в файле DROBY.PAS и откомпилируем наш модуль. Для этого можно воспользоваться внешним компилятором, поставляемым вместе с Turbo Pascal. Команда будет выглядеть так: TPC DROBY.PAS. Если в тексте нет синтаксических ошибок, получим файл DROBY.TPU, иначе будет соответствующее сообщение с указанием строки, содержащей ошибку. Другой способ компиляции модуля — в среде программирования Turbo Pascal выбрать в пункте меню Run подпункты Make или Build (при этом должна быть включена компиляция на диск).


Случайные файлы

Файл
169927.rtf
59507.rtf
саж.doc
109537.doc
87913.doc




Чтобы не видеть здесь видео-рекламу достаточно стать зарегистрированным пользователем.
Чтобы не видеть никакую рекламу на сайте, нужно стать VIP-пользователем.
Это можно сделать совершенно бесплатно. Читайте подробности тут.