Лекция 7.pptx
- Количество слайдов: 17
ПРОЦЕДУРЫ В ЯЗЫКЕ PASCAL
Что такое процедура и зачем она нужна Часто некоторую последовательность действий требуется повторить в нескольких местах программы. Чтобы не тратить время и усилия на копирование, в языке программирования Pascal предусмотрены средства для организации подпрограмм. Программист имеет возможность присвоить последовательности операторов некоторое имя и использовать это имя в качестве сокращенной записи в тех местах, где встречается соответствующая последовательность действий. Таким образом, ПРОЦЕДУРА - это именованная последовательность операторов. Использование процедур позволяет: 1)сокращать текст программы. Процедура является одним из фундаментальных инструментов, оказывающих большое влияние на стиль, качество и надежность разработки программных систем. Она выступает как средство декомпозиции программы на логически связанные, но замкнутые компоненты.
2)повышает читаемость программ, облегчает отладку и модификацию. Поэтому рекомендуется использовать процедуры даже в тех случаях, когда они вызываются однократно и, следовательно, отсутствует мотив, связанный с сокращением программы. 3) Разбиение программы на отдельные связанные процедуры позволяет также вести разработку коллективу программистов. Наконец, если в нескольких местах программы последовательности операторов близки, но не идентичны, то задавая параметры в процедуре, ее можно настроить на конкретное выполнение. В сущности вы уже пользовались процедурами, когда записывали команды ввода и вывода. Read, Readln, Write и Writeln – это тоже процедуры. Но они уже готовы и мы пользуемся ими, даже не задумываясь, как они реализованы. Это так называемые стандартные процедуры, которые поставляются вместе с транслятором языка PASCAL. Кроме стандартных процедур в языке предусмотрено создание своих (пользовательских) процедур.
Описание процедуры Подпрограмма должна быть описана до того, как она будет использована в программе. Любая процедура начинается с заголовка, который, в отличие от заголовка основной программы, в процедуре является обязательным. Заголовок состоит из зарезервированного слова Procedure, за которым следует имя процедуры, а далее в круглых скобках - список формальных параметров. Program Name; . . . {Разделы описания меток, констант, типов и переменных}. . . Procedure <имя процедуры>(<список формальных параметров>); {Раздел описаний} Begin {Раздел операторов}; end; Begin {Начало тела программы} . . . {Тело программы, операторы}; End.
За заголовком могут идти такие же разделы, что и в основной программе (описание констант, типов, переменных, процедур. . . ). В отличие от основной программы процедура завершается не точкой, а точкой с запятой. Примеры процедуры Прежде чем перейти к формальному описанию процедур и их использованию, рассмотрим простой пример. Мы уже рассматривали алгоритм поиска максимального из двух чисел. Этот алгоритм оформлен в виде процедуры. В головной программе происходит обращение к данной процедуре. От этого алгоритм нахождения максимального среди нескольких чисел стал очень наглядным и легко модифицируемым, если потребуется изменить количество чисел.
program MAX 4; var A, B, C, D, R 1, R 2, R 3: integer; { ОПИСАHИЕ ПPОЦЕДУPЫ MAX } procedure MAX(N 1, N 2: integer; Var R: integer); { Пpоцедуpа находит максимальное из двух заданных чисел } { ПАPАМЕТPЫ пpоцедуpы } { Входные паpаметpы: N 1 и N 2 - заданные числа } { Выходной паpаметp: R - значение максимального числа } begin if N 1>N 2 then R: =N 1 else R: =N 2 end; { - начало тела главной программы} begin writeln('<<< НАХОЖДЕНИЕ МАКСИМАЛЬНОГО ИЗ ЧЕТЫPЕХ ЦЕЛЫХ ЧИСЕЛ >>>'); writeln(' программа закончит работу, если все числа равны 0'); writeln;
repeat write('Первое число = ? '); readln(A); write('Втоpое число = ? '); readln(B); write('Тpетье число = ? '); readln(C); write('Четвеpтое число = ? '); readln(D); if (A=B) and (B=C) and (C=D) then writeln(' все числа pавны') else begin Max(A, B, R 1); | Max(C, D, R 2); | вызовы процедур Max(R 1, R 2, R 3); | writeln('Максимальное число = ', R 3); writeln end until (A=0) and (B=0)and (c=0) and(d=0); end.
Пример. Написать процедуру рисующую строку из любых заданных пользователем символов. Количество символов и сами символы задаются пользователем в основной программе. Program Name; . . . {Разделы описания меток, констант, типов и переменных}. . . Procedure Line(ch: char; ln: integer); var symbol: integer; Begin {Начало тела процедуры} For symbol: =1 to ln do Write (ch); end; {Конец тела процедуры} Begin {Начало тела программы}. . . read(a, b); {Задаются символ и длина строки} line(a, b); {Вызов процедуры}. . . End.
Параметры процедуры Procedure <имя>(список парам 1: тип 1; список парам 2: тип 2, . . . ; var список перем 1: тип 1; var список перм 2: тип 2, . . . ); Параметры, описанные в заголовке процедуры, называются ФОРМАЛЬНЫМИ. Они указывают, с какими параметрами можно обращаться к этой процедуре (количество, их последовательность, типы). В заголовке процедуры они задаются в виде списка. Параметры, задающиеся при вызове процедуры в самой программе называются ФАКТИЧЕСКИМИ. Каждый из формальных параметров может принадлежать к одной из следующих категорий: - 1) параметры-значения (эти параметры в подпрограмме не могут меняться, их называют входными параметрами); - 2) параметры-переменные (эти параметры могут изменить свое значение в процедуре, поэтому их используют для результатов работы процедуры и называют выходными);
Примечание: В действительности существует еще несколько категорий типов параметры-процедуры, параметрыфункции. Но эти типы параметров мы рассмотрим позднее. Списку параметров-переменных должно предшествовать ключевое слово Var. Действие слова Var распространяется до ближайшей точки с запятой. Рекомендуется сначала в списке параметров указывать входные параметры, затем выходные. Отделяются эти группы друг от друга точкой с запятой. Для каждого формального параметра в заголовке должен быть указан его тип. Параметры одного типа можно объединять в группу. Между описаниями отдельных типов ставится точка с запятой. Рассмотрим примеры заголовков процедур. Procedure Ar(A: integer; B, C: real; Var d: boolean); Этот заголовок указывает, что в процедуре три входных параметра и один выходной. Procedure Br(A: integer); Этот заголовок указывает, что в процедуре один входной параметр и нет ни одного выходного. Примером такой процедуры может быть процедура, выводящая на экран заданное число звездочек. В этом случае требуется только входной параметр, назад в программу ничего не надо передавать.
Procedure Gr(Var G: real); Данный заголовок указывает, что в процедуре имеется только один параметр - выходной. Но следует отметить, что он может Быть одновременно и входным. Procedure Cr; Это процедура без параметров. Примером процедуры без параметров может служить процедура чистки экрана. Тип формального параметра может быть практически любым, однако в заголовке процедуры нельзя вводить новые типы. Например, нельзя писать Procedure Mix(A: array[1. . 100] of real); Для того, чтобы правильно записать заголовок, потребуется в основной программе ввести новый тип: Type mas=array[1. . 100] of real; После чего заголовок будет иметь вид: Procedure Mix(A: mas);
Глобальные и локальные описания При использовании процедур возникает разделение данных на 1) глобальные и 2) локальные. Глобальные константы, типы, переменные -это те, которые объявлены в программе вне процедур. Локальные это те описания, которые описаны внутри процедуры. Обмен информацией между основной программой и процедурой может осуществляться только с помощью глобальных параметров. Процедура может использовать глобальные параметры двояким образом: непосредственно обращаясь к глобальному параметру по его имени или используя механизм формальных параметров. Процедура может непосредственно использовать любые глобальные параметры, за исключением тех, которые имеют те же имена, что и ее локальные параметры.
Вызов процедуры Для вызова процедуры из основной программы следует записать оператор, состоящий из имени процедуры и списка фактических параметров, которые должны совпадать по количеству, последовательности и типам со списком формальных параметров. Например, если мы имеем процедуру, которая вычисляет значение заданного числа в заданной степени и имеет заголовок: Procedure ST(A: real; N: integer; Var Rez: real); где A - заданное число; N - степень числа; REZ - значение N-ой степени числа А. Вызов процедуры может иметь вид: ST(10. 5, 9, D); Эта запись означает, что требуется вычислить девятую степень числа 10. 5 Входные параметры задаются в виде значений. Результат вычисления будет записан в переменную D, которая должна иметь тип real.
Вызов процедуры может иметь и следующий вид: ST(A 1, A 2, A 3); ST(A 1, 7, A 3); ST(Num, S+1, R); Подчеркиваем еще раз, что количество фактических параметров, их последовательность и тип должны совпадать со списком формальных параметров. Более подробно механизм передачи фактических параметров выглядит следующим образом. При вызове процедуры каждой локальной переменной, описанной внутри процедуры и каждому параметру-значению из списка фактических параметров отводится место для хранения данных в специальной области памяти, называемой стеком. Эти места принадлежат переменным ровно столько времени, сколько выполняется процедура. Причем ячейки, соответствующие входным параметрам, сразу заполняются конкретным содержимым, заданным в вызове подпрограммы. По другому организуется работа с параметрами-значениями (выходными параметрами). Вместо копии значения процедура получает разрешение работать с тем местом, где постоянно хранится значение данной переменной (т. е. получает адрес этого места). После завершения работы подпрограммы стек с локальными переменными теряется и, следовательно, теряются их значения.
Опережающее описание Можно ли использовать ранее описанную подпрограмму в другой подрограмме? ? Да можно. Так как она описана выше, то след подпрограмма ее видит. А вот можно ли сделать наоборот, т. е. использовать в подпрограмме еще не описанную подпрограмму, которая будет потом описана ниже? Выход из этого затруднения предоставляет так называемое опережающее описание. В Паскале допускается применение опережающего описания используемой подпрограммы, которое состоит из ее заголовка, за которым следует зарезервированное слово FORWARD. В этом случае полный текст подпрограммы может быть расположен дальше в любом месте раздела описаний процедур.
Пример. Составить в программе процедуры, кот. могут использовать сами себя. Program K; var i: integer: j: real; procedure a(x: integer); forward; {Опережающее описание} procedure b(y: real); begin {Начало тела процедуры}. . . a(i); {Вызов еще не определенной процедуры} end; {Конец тела процедуры} procedure a; begin {Начало тела процедуры}. . . b(j); end; {Конец тела процедуры} Begin {Начало тела программы}. . . read(c, d); a(c); b(d); . . . End.
Пример. Составить программу с процедурой для вычисления площади круга по заданному радиусу. Program Krug; Var Rad, S: real; Procedure ploschad(r: real; var pl: real); begin pl: =pi*r*r; end; Begin Write('введите значение Rad: '); Readln(Rad); ploschad(Rad, S); Writeln('площадь круга равна: ', S: 6: 3); Writeln('для выхода нажми ввод'); Readln; End.


