Информатика -продвинутый курс

       

ПРОЦЕДУРЫ И ФУНКЦИИ


Описание и вызов. В Паскале подпрограммы называются процедурами и функциями и описываются в разделе с тем же названием.

Процедура имеет такую же структуру, как и программа, но с двумя отличиями:

• заголовок процедуры имеет другой синтаксис и включает служебное слово procedure;

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

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

procedure <имя> (<список описаний формальных параметров>) Описание формальных параметров может иметь вид

<список имен>: <тип> или var <список имен>: <тип>

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

Оператор вызова процедуры имеет вид

<имя процедуры> (<список выражений>);

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

Параметры-переменные следует использовать для представления результатов процедуры.

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



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


Заметим, что процедура в программе выполняется пять раз.

Программа 18

program section;

var x:integer;

procedure line(a:integer;c:char) ;

var j:integer;

begin

for j:=l to a do write (c);

writeln

end;

begin

line(35,'-'); writeln('таблица квадратных корней');

line(35,'-');

for x:=l to 10 do writeln(x:8,sqrt(x):8,4);

line (35,'-'); writein('таблица натуральных логарифмов');

line(35,'-');

for x:=l to 5 do writein(x:8,In(x):8:4);

line(35,'*')

end.

Функция - это подпрограмма, определяющая единственное скалярное, вещественное или строковое значение. Отличия подпрограммы-функции от процедуры:

• заголовок функции начинается со служебного слова function и заканчивается указанием типа значения функции:

function <имя> (список описаний формальных параметров): <тип>;

•раздел операторов функции должен содержать хотя бы один оператор присваивания имени функции;

• обращение к функции - не оператор, а выражение вида

<имя функции> (<список фактических параметров>).

Функции (и процедуры) могут использовать свое имя в собственном описании, т.е. могут быть рекурсивными.

Пример: составим программу, которая для заданных четырех натуральных чисел а, b, с, d напечатает наибольшие общие делители первой и второй пар чисел и сравнит их по величине.

В программе определим рекурсивную функцию nod(x,y) по формулам

|

x, если у = 0

nod(x,y) = | nod(y.x). если х < у

| nod(x mod у,у), если х > у

Применяя эти формулы к числам 21 и 15, последовательно находим nod(21,15) = nod(6,15) = nod(15,6) = nod(3,6) = nod(6,3) = nod(0,3) = nod(3,0) = 3.

Программа 19

program four;

var a,b,c,d,m,n:integer;

function nod(x,у:integer):integer;

var h:integer;

begin

if y=0 then h:=x

else if x<y then h:=nod(y,x)

else h:=nod(x mod у, у);

nod: =h end;

begin

writeln('введите 4 натуральных числа');

read(а,Ь,с,d); writeln;

m:=nod(a,b); n:=nod(c,d);

writeln('нод(',а,',',b,')=',m);

writeln('нод(',c,',',d,')=',n);



if m>n then writeln('первый > второго')

else if m<n then writeln ('первый < второго')

else writeln('нод пар равны') end.

Внешние библиотеки.

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

Бывают случаи, когда одни и те же подпрограммы могут использоваться в различных программах одного и даже нескольких пользователей. В подобных ситуациях целесообразно создавать внешние подпрограммы, которые можно в необходимый момент подключать в любые программы. Как правило, внешние подпрограммы объединяют в отдельные пакеты, так называемые, библиотеки внешних подпрограмм. Могут создаваться личные библиотеки, специализированные библиотеки коллективного пользования и др. С одной из таких библиотек - встроенной библиотекой стандартных подпрограмм - пользователи имеют дело практически всегда. В состав этой библиотеки входят процедуры и функции вычисления значений ряда элементарных функций: синуса, косинуса, экспоненты и т.д., процедуры и функции обработки символьных величин, процедуры ввода-вывода и др. (список их приведен в конце § 3). Встроенная библиотека подключается к любой программе автоматически при компиляции. Поэтому откомпилированный файл с расширением .corn (иногда называемый «комовским»), как правило, занимает в 8 -10 раз больше места в памяти, чем исходный текст.

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



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

Программа 20

procedure PRIVET;

var a: char;

begin

cirscr; gotoxy(20,10) ;

write('здравствуйте , желаю успехов !') ;

repeat (цикл позволяет)

gotoxy(35,50);write('пробел'); (сменить экран}

read(kbd,а); (по нажатию клавиши)

until а=' '; (* 'пробел' )

cirscr;

end;

procedure STEPEN(a,b:real;var y:real);

begin

y:=exp(b*ln(a)) ;

end;

function MEXP(x:real):real;

begin

mexp:=l+x+x*x/2+x*x*x/6+x*x*x*x/24;

end;

Пусть представленные три подпрограммы записаны в файл с именем lab.pas. А теперь составим программу, использующую созданную внешнюю библиотеку.

Программа 21

program primeri;

($i lab) (директива подключения библиотеки} var a,b : real;

begin

PRIVET;

STEPEN(2,4,a); writeln('2 в степени 4 =',a); b:=MEXP(l);

write('машинная exp(1)=',EXP(1):6:4,' моя

exp(1)=',b:6:4);

end.

В программе используется стандартная функция - экспонента ЕХР(1) и наша подпрограмма МЕХР(1).

Модули используют в более поздних версиях Паскаля для создания библиотек и разделения больших программ на логически связанные независимые друг от друга составные части. В состав модуля входят следующие разделы: заголовок, интерфейс, реализация, инициализация. Заголовок необходим для ссылок на модуль. Интерфейс содержит объявления, включая процедуры и функции, представленные списком заголовков и доступные пользователям в теле основной программы. Раздел «реализация» содержит тела процедур и функций, перечисленных в интерфейсной части модуля. Раздел «инициализация» содержит операторы, необходимые для инициализации модуля. Таким образом модуль - это набор констант, типов данных, переменных, процедур и функций.


Каждый модуль компилируется отдельно; результат компилляции - файл с расширением .tpu (Turbo Pascal Unit). Каждый элемент модуля можно использовать в программе пользователя без дополнительного объявления, для чего достаточно записать имя используемого модуля в директиве Uses в начале программы после его заголовка.

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

uses <имя модуля>

Программист может сам создать модуль. Ниже приведен пример с соответствующими комментариями.

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

Будем представлять комплексные числа парами действительных: (а, b). Как известно, действия над ними выполняются по правилам

(a,b) + (c.d) = (a+c,b+d),

(a,b)-(c,d)=(a-^,b-d),

(a,b) * (c,d) = (a*c-b*d , a*d+b*c),

(a,b) / (c,d) = ( (a*c+b*d)/(c*c+d*d), (b*c-a*d)/(c*c+d*d)).

Создаваемый модуль будет включать четыре процедуры: Sum - сумма, Raz -разность, Proiz - произведение, Chastn - частное.

Этот модуль может быть отдельно откомпилирован. После этого любая программа, написанная на Паскале, может получить доступ к интерфейсным объектам (в данном случае - процедурам) этого модуля с помощью директивы Uses CompChisla.

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

Программа 22

unit CompChisla;

interface

procedure Sum(a,b,c,d: real; var x,y: real);

procedure Raz(a,b,c,d: real; var x,y: real);

procedure Proiz (a,b,c,d: real; var x,y:

real);

procedure Chstn(a,b,c,d: real; var x,y:

real);

implementation

procedure Sum;

begin x:=a+c;

y:=b+d end;

procedure Raz;

begin x:=a-c; y:=b-d end;

procedure Proiz;

begin x:=a*c-b*d; y:=a*d+b*c

end;

procedure Razn;

var z:real;

begin z:= c*c+d*d; x:=(a*c+b*d)/z; y:=(b*c-a*d)/z end;

end.

Контрольные вопросы

1. Какова структура процедуры? функции?

2. Какие параметры называют формальными и какие - фактическими?

3. В чем различие между локальными и глобальными переменными?

4. В чем сходство и различие между процедурой и модулем?


Содержание раздела