Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

информатика_книги / Информатика. Теория и практика_Острейковский В.А, Полякова И.В_2008 -608с

.pdf
Скачиваний:
159
Добавлен:
06.06.2015
Размер:
7.43 Mб
Скачать

7.1.7. Процедуры, функции и рекурсии языка Паскаль

При создании программы для решения сложной задачи выполняется разделение (декомпозиция) этой задачи на подзада- чи, а подзадач — на еще меньшие подзадачи и т. д.

Турбо Паскаль имеет различные средства для деления программы на части. На верхнем уровне деления (больших задач) — это модули, на нижнем уровне (элементарных подзадач) — это подпрограммы, которые в Турбо Паскаль могут быть двух видов: процедуры и функции.

Подпрограммой в языке Турбо Паскаль называется особым образом оформленный фрагмент программы, имеющий собственное имя. Упоминание этого имени приводит к активизации подпрограммы и называется ее вызовом. Сразу после активизации подпрограммы начинают выполняться входящие в нее операторы. После выполнения последнего из них управление возвращается обратно в основную программу, и выполняются операторы, стоящие непосредственно за оператором вызова подпрограммы. Язык Паскаль имеет богатую библиотеку программных заготовок (модулей), существенно облегчающих разработку прикладных программ. Такими модулями являются SYSTEM, DOS, CRT, PRINTER, GRAPH, OVERLAY, ТУРБО3 и GRAPH3. Модули GRAPH, ТУРБО3 и GRAPH3 выделены

âотдельные TPU-файлы, а остальные входят в состав библиотечного файла ТУРБО.TPL. Лишь один модуль — SYSTEM — подключается к любой программе автоматически, все остальные становятся доступны только после указания их имен в списке, следующем за словом USES.

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

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

âкачестве средства структурирования программы. Механизм процедур позволяет при разработке программы методом после-

491

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

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

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

Функция — это специальная форма процедуры, предназна- ченная для вычисления по заданным параметрам одного-един- ственного значения. Для вызова функции, в отличие от процедуры, ее имя нужно записать в виде компоненты выражения, например: ó:= F(x), ãäå F — имя функции; õ — фактический параметр. Вычисленное значение функции связывается c именем функции, что позволяет обойтись без промежуточных параметров, передающих вычисленное значение. С операционной точ- ки зрения функция в языке программирования аналогична функции в математике.

492

Описание процедуры на языке Паскаль:

procedure Имя (Список формальных параметров);блок; оператор обращения к процедуре:

Имя (Список фактических параметров); описание функции:

function Имя (Список формальных параметров) : тип; блок; обращение к функции — компонента выражения; Имя (Список фактических параметров).

В теле функции должен содержаться один или несколько операторов присваивания значения идентификатору функции:

Èìÿ:= åõð;

Пример:

Var a:real;

procedure sum(x,y : real; var z : real); Begin

z: = x+y {var нужно, чтобы возвратить значение}

End;

Begin

sum (3.1, 2.2, s); writeln(s);

End.

Тот же результат достигается с помощью функции: function sum (x,y: real):real;

Begin writeln(sum(3.1,2.2);

End.

Стандартные функции и процедуры языка Паскаль:

Abs(X) — вычисляется абсолютное значение Х. Exp(X) — Е возводится в степень Х.

Ln(X) — вычисляется натуральный логарифм Х. Sqr(X) — X возводится в квадрат.

Sqrt(X) — вычисляется квадратный корень из Х.

Sin(X), Cos(X), Arctan(X) — тригонометрические функции (аргумент задается всегда в радианах).

Trunc(X) — определяет целую часть числа, тип результата Longint.

Round(X) — округляет до целого.

493

Chr(I) (I — целое число) — определяет символ, порядковый номер которого равен I.

Ord(X) (X — порядковый) — определяет порядковый номер символа в наборе символов.

Pred(X) (X — порядковый) — находит предшествующий элемент.

Succ(X) (X — порядковый) — находит последующий элемент.

Odd(X) (X — целого типа) — определяет четность числа: если Х — нечетный, то результат принимает значение True, если четный — False.

Eoln(X) (X — файловая переменная) — результат принимает значение True, если при чтении текстового файла достигнут конец текущей строки. В остальных случаях результат равен False.

Eof(X) (X — файловая переменная) — результат принимает значение True, если при чтении текстового файла достигнут конец файла. В остальных случаях результат равен False.

Dec(X[,i]) — уменьшает значение Х на i, при отсутствии i — на 1.

Inc(X[,i]) — увеличивает значение Х на i, при отсутствии i — на 1.

Frac(X) — определяет дробную часть аргумента.

Int(X) — определяет целую часть аргумента. Тип результата — Real.

Random (X) — равномерное псевдослучайное число 0 <= I < X, при отсутствии Х — интервал чисел от 0 до 1.

Математические функции, не представленные в языке Паскаль в явном виде:

десятичный логарифм: Lg (X ) = Ln(X )/Ln(10); возведение в степень: Y = M n Y := Exp(n*Ln(M ));

A = 165 A := Exp(5*Ln(16));

тангенс угла: Tg (X) = Sin (X )/Cos (X ); котангенс угла: Ctg (X ) = Cos (X )/Sin (X ); секанс угла: Sc (X ) = 1/Cos (X ); косеканс угла: Csc (X ) = 1/Sin (X );

арксинус числа: Arcsin (X ) = ArcTan (X/Sqrt(1 – X*X )); арккотангенс числа: Arcctg(X ) = Pi/2 — ArcTan (X ); арккосинус числа: Arccos (X ) = Pi/2 — ArcTan (X/Sqrt(1 –

X*X )).

494

Тригонометрические функции. Параметр тригонометриче- ских функций всегда задается в радианах. Для перевода из градусов в радианы и наоборот используются соотношения:

1 ðàä = 180 /Pi = 57 17 45 ; 1 = Pi/180 ðàä = 0,0174 ðàä.

Нестандартные процедуры и функции. В большинстве случа- ев некоторые специфичные для данной прикладной программы действия не находят прямых аналогов в библиотеках языка Турбо Паскаль, и тогда программисту приходится разрабатывать свои, нестандартные процедуры и функции.

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

Функции представляют собой группу операторов, в результате выполнения которых вычисляется одно значение, присваиваемое имени функции. В заголовке функции за ключевым словом Function указывается ее имя, а в скобках — список параметров со своими описаниями. В заголовке определяется тип значения, присваиваемый функции. Как правило, окончательный результат присваивается функции в конце тела функции. Общая структура записи функции имеет вид:

Function F(q1:T1,q2:T2, ...):T;

<Раздел описания локальных меток, констант, типов и переменных>

<Раздел описания внутренних процедур и функций>

Begin

S1;... S2; <Операторы>

F:= <Обязательный оператор, который присваивает имени функции значение результата>

End;

где F — имя функции; qi — имена формальных параметров; Ti — типы формальных параметров; T — тип результата; Si — операторы тела функции.

495

Обращение к функции осуществляется в правой части оператора присваивания, при этом в выражении записываются имя функции и фактические параметры в виде:

X:= F(b1, b2,...),

где F — имя функции; bi — фактические параметры. После вы-

полнения функции вычисленное значение присваивается имени функции и передается в выражение.

Рекурсия. Если процедура или функция в ходе выполнения вызывает саму себя, то она является рекурсивной. Использование рекурсии позволяет легко запрограммировать вычисления по рекуррентным формулам. Например, для вычисления факториала существует рекуррентная формула: 0!=1; äëÿ âñåõ n>0 n!=n*(n-1)!

В случае использования рекурсии функция вычисления факториала имеет следующий вид:

Function Fact(k:byte):longint; Begin

if k=1 then Fact:=1 else Fact:=k*Fact(k-1);

End.

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

âподпрограмме получить несколько результатов или выполнить действие над параметрами. Описание процедуры включает

âсебя заголовок процедуры, разделы описаний, тело процедуры. В заголовке после ключевого слова Procedure указывается имя процедуры, в скобках — список формальных параметров со своими описаниями. Эти параметры используются только

âтеле подпрограммы и локальны по отношению к ней. Общая структура записи процедуры имеет следующий вид:

Procedure P(r1,r2:T1;var q1:T2;q2:T3;...);

<Разделы определений и описаний локальных параметров и подпрограмм)

Begin

S1;.... S2; End;

где P — имя процедуры; ri è qi — имена формальных параметров, причем ri — параметры-значения, qi — параметры-пере-

496

менные; Ti — типы формальных параметров; Si — операторы процедуры.

Обращение к процедуре осуществляется оператором процедуры, в котором записываются имя процедуры и ее фактиче- ские параметры P(b1, b2, …), ãäå bi — фактические параметры, которые соответствуют формальным по количеству, типу и месту расположения.

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

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

7.1.8. Структурированные типы данных

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

При описании массива за ключевым словом Array в квадратных скобках указывается тип-диапазон, а за ключевым словом of следует тип элементов. Тип-диапазон задается левой и правой границами изменения индекса массива.

Var a: Array[1..10,1..5] of Real; {Двухмерный массив, состоящий из 50 элементов (10 строк, 5 столбцов) вещественного типа};

b:Array[1..50] of Char;{Одномерный массив из 50 символов};

c:Array [-3..4] of Boolean;{Одномерный массив из 8 элементов с порядковыми номерами от –3 до 4, тип элементов — логический}.

При компиляции программы в оперативной памяти резервируется объем памяти, необходимый для размещения всего

497

объявленного массива. Если количество элементов массива заранее не известно или может изменяться, то необходимо зарезервировать объем памяти для размещения максимально необходимого количества элементов.

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

b[17]:= 'F'; C[-2]:= a[1,1] > a[2,2];

Массивы могут быть заданы в разделе объявления констант. Двухмерные и многомерные массивы объявляются обычно с использованием раздела Type:

Const n= 10; m= 15; p= 20;

MA:Array[1..2, 1..3] of Integer= ((3,5,6), (2,1,7));

{Значения постоянного массива}

Type ms= Array[1..n, 1..m] of Real; Var a1: Array[1..p] of ms;

a2,a3: ms;

В качестве примера рассмотрим некоторые операции с массивами:

1. Ввод с клавиатуры двух-

2. Вывод двухмерного массива

мерного массива A[N,M]:

A[N,M] на печать:

For i:= 1 to n do

For i:= 1 to n do

For j:= 1 to m do

Begin

Begin

For j:= 1 to m do

Writeln('Введите а[',i,',',j,']')

Write (a[i,j]:6:3);

Readln (a[i,j]);

Writeln;

End;

End;

3. Формирование двух массивов с помощью датчика слу- чайных чисел:

Randomize; For i:= 1 to k do

Begin

Y[i]:= Random; {Для задания массива Y 0 < Yi < 1}

X[i]:= Random(100); {Для задания массива X 0 < Xi < 100}

End.

498

Символы и строки символов. Каждый из символов имеет свой уникальный номер — êîä. Соответствие кода и внешнего вида символа называется кодовой таблицей, оно зависит от страны (языка), от операционной системы, от устройства, на которое символ выводится. Для преобразования кода в символ в языке Паскаль существует функция Chr(êîä), для преобразования символа в код — функция Ord(символ). Например, в результате выполнения оператора WriteLn(Chr(68)); на экране появится символ D, так как его код — 68, а при выполнении WriteLn(Ord(’D’)); — число 68, так как именно ему соответствует символ D.

Переменная для хранения одного символа имеет тип char. Символьную константу в программе можно указать двумя способами: ‘D’ или #68. Первый способ удобнее использовать, когда символ легко ввести с клавиатуры.

Обрабатывать текстовую информацию удобнее крупными частями. Строка символов в языке Паскаль — это последовательность символов длиной от 0 до 255, ее тип имеет название String. Фактически это массив, нулевой элемент которого содержит логическую длину строки. Если там находится #0, то считается, что строка пуста, если #20, значит, в строке 20 символов (тип всех, в том числе и нулевого, элементов — char, поэтому перед 0 и 20 стоит знак #). Физическая же длина строки задается при написании программы (по умолчанию — 255 байт под содержимое плюс 1 байт, отвечающий за длину), например:

var

s1: String;

s2: String[10];

переменная s1 будет занимать в памяти 256 байт, а s2 — 11. Доступ к каждому элементу аналогичен доступу к элемен-

там массива: имя_строки[значение_индекса].

Процедуры для работы со строками (вызываются как отдельные операторы):

Delete(<Строковая_переменная>, <Позиция>, <Количество_символов>) — удаляет из строки указанное количество символов, начиная с указанной позиции.

Insert(<Исходная_строка>, <Строковая_переменная>, <Позиция>) — вставляет последовательность символов в строковую переменную.

499

Str(<Число>, <Строковая_переменная>) — преобразует число в строку. После числа может стоять спецификация формата. Например, после выполнения оператора Str(f:7:3,s); ïðè f = –1,8

âстроке s будет находиться: ’ —1.800’. (Val(<Строка>, <Численная_переменная>, <Код_результата>) — если строка содержит число, оно будет помещено в численную переменную и переменная «Код результата» будет равна 0. Если же при преобразовании произойдет ошибка (будет обнаружен недопустимый

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

Функции для работы со строками (должны быть частью выражений соответствующих типов):

Length(<cтрока>) — возвращает целое число — логическую длину строки.

Copy(<Строка>, <Позиция>, <Размер>) — возвращает подстроку из указанной строки.

Pos(<Искомая_подстрока>, <Строка>) — возвращает число — позицию первого вхождения подстроки в строку — или 0, если строка не содержит такой последовательности символов ãäå-òî внутри себя.

Запись (структура данных). Тип-запись включает ряд компонент, называемых полями, которые могут быть разных типов.

Формат объявления типа-записи:

Type

<èìÿ òèïà> = record < ïîëå 1>: òèï 1;

..............

<ïîëå N>: òèï M End;

Type

Complex = record Re, Im: real;

End;

Data = record Year: Integer;

500

Соседние файлы в папке информатика_книги