Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Описание подпрограммы состоит из заголовка и тела подпрограммы.
Заголовок процедуры имеет вид:
Procedure < имя > [список формальных параметров];
Заголовок функции:
Function < имя > [список формальных параметров]: тип возвращаемого функцией результата.
Список формальных параметров необязателен и может отсутствовать. Если же он есть, то в нем должны быть перечислены имена формальных параметров и их типы, например:
Procedure SB (a: real; b;integer; c:char),
Параметры в списке отделяются друг от друга точками с запятой. Несколько следующих подряд однотипных параметров можно объединить в подсписки, например,
Вместо a: real; b: real можно написать а,b: real. Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний: все переменные из этого списка могут использоваться в любых выражениях внутри подпрограммы. Так осуществляется настройка алгоритма подпрограммы на конкретную задачу.
Пример программы, которая заполняет область экрана 8´8 символов в соответствии с рисунком:
Program DemoProcedure;
Uses CRT;
Var x,y: integer;
Procedure A1;
begin
for y:=1 to 4 do
for x:=1 to 4 do
begin
gotoxy(x,y);
write(#176);
end;
end;
Procedure A2;
begin
for y:=5 to 8 do
for x:=5 to 8 do
begin
gotoxy(x,y);
write(#176);
end;
end;
Procedure A3;
begin
for y:=1 to 4 do
for x:=5 to 8 do
begin
gotoxy(x,y);
write(#178);
end;
end;
Procedure A4;
begin
for y:=5 to 8 do
for x:=1 to 4 do
begin
gotoxy(x,y);
write(#178);
end;
end;
Begin
a1;
a2;
a3;
a4;
readln;
End.
Пример наглядно демонстрирует структуру программ с использованием процедур, когда раздел описаний больше, чем исполнительная часть программы.
Задача существенно упрощается, если использовать процедуры с параметрами.
Program DemoProcedureParam;
Uses CRT;
Var x,y: integer;
Procedure A1(a,b,c,d:integer);
begin
for y:=a to b do
for x:=c to d do
begin
gotoxy(x,y);
write(#176);
end;
end;
Procedure A2(a,b,c,d:integer);
begin
for y:=a to b do
for x:=c to d do
begin
gotoxy(x,y);
write(#178);
end;
end;
Begin
clrscr;
a1(1,4,1,4);
a2(5,8,1,4);
a2(1,4,5,8);
a1(5,8,5,8);
readln;
End.
Если ввести параметр символьного типа, то в данной задаче можно вообще ограничится обной процедурой.
Program DemoProcedure;
Uses CRT;
Var x,y: integer;
Procedure A1(a,b,c,d:integer; ch:char);
begin
for y:=a to b do
for x:=c to d do
begin
gotoxy(x,y);
write(ch);
end;
end;
Begin
clrscr;
a1(1,4,1,4,#176);
a1(5,8,1,4,#178);
a1(1,4,5,8,#178);
a1(5,8,5,8,#176);
readln;
End.
Таким образом, выигрыш в использовании процедур с параметрами в больших задачах налицо. Здесь проявляется еще одно преимущество использования процедур – процедуру описывают один раз, а вызывать можно столько, сколько потребуется.
Рассмотрим пример использования функций. В Турбо Паскаль нет операции возведения в степень, однако, с помощью встроенных функций Ln(x) и ехр(х) можно создать функцию с новым именем, например, stepen, которая будет возводить любое вещественное число в любую вещественную степень.
Пример:
Var
х,у: real;
Function Stepen (a,b: real): real;
Begin { Stepen }
if a>0 then Stepen: = exp(b* ln(a»
else if a<0 then Stepen: = exp (b* ln(abs(a)))
else if b=0 then Stepen:=l
else Stepen:=0
End { Stepen }
Begin
repeat
readln (x,y);
writeln (Stepen (x,y): 12:10; Stepen (x,-y): 15:5;
Until EOF
End.
В программе вводится пара чисел X и Y и выводится на экран дисплея результат возведения X сначала в степень +Y, а затем в степень -Y. Для выхода из программы нужно ввести Ctrl -Z и Enter.
Для вызова функции Stepen мы просто указали ее в качестве параметра при обращении к встроенной процедуре Writeln. Параметры X, Y в момент обращения к функции - это фактические параметры. Они подставляются вместо формальных параметров А и В в заголовке функции и затем над ними осуществляются нужные действия. Полученный результат присваивается идентификатору функции - именно он и будет возвращен как значение функции при выходе из нее. В программе функция Stepen вызывается дважды - сначала с параметрами X и Y, а затем X и - Y, поэтому получатся два новых результата.
Механизм замены формальных параметров на фактические позволяет нужным образом настроить алгоритм, реализованный в подпрограмме. Необходимо следить за тем, чтобы количество и тип формальных параметров строго соответствовали количеству и типам фактических параметров в момент обращения к подпрограмме. Смысл используемых фактических параметров зависит от того, в каком порядке они перечислены при вызове подпрограммы. В примере первый по порядку фактический параметр будет возводиться в степень, задаваемую вторым параметром, а не наоборот. Необходимо следить за правильным порядком перечисления фактических параметров при обращении к подпрограмме.
Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-константой. Если параметры определяются как параметры-переменные, перед ними необходимо ставить слово Var, если константы - слово Const, например:
Procedure MyProcedure(Var a: real;b: real; const c: string);
Здесь, a - параметр-переменная, b - параметр-значение, с - параметр-константа.
Определение формального параметра тем или иным способом существенно, в основном, только для вызывающей программы. Если формальный параметр объявлен как параметр-переменная, то при вызове подпрограммы ему должен соответствовать фактический параметр нужного типа. Если формальный параметр объявлен как параметр-значение или параметр-константа, то при вызове ему может соответствовать произвольное выражение.
Например, если для предыдущего примера был бы использован такой заголовок функции
Function Stepen(var a,b: real): real;
то при втором обращении к функции компилятор указал бы на несоответствие типа фактических и формальных параметров. (Параметр - Y есть выражение, в то время как соответствующий ему формальный параметр описан как параметр-переменная).
Рассмотрим подробнее, как осуществляется замена формальных параметров на фактические в момент обращения к подпрограмме.
Если параметр определен как параметр-значение, то перед вызовом подпрограммы это значение вычисляется, полученный результат копируется во внутреннюю память и передается подпрограмме. Важно учесть, что даже если в качестве фактического параметра указано простейшее выражение в виде переменной или константы, все равно подпрограмме будет передана лишь копия переменной (константы). Любые возможные изменения в подпрограмме параметра-значения никак не воспринимаются вызывающей программой, так как в этом случае изменяется копия фактического параметра.
Если параметр определен как параметр-переменная, то при вызове подпрограммы передается сама переменная, а не ее копия {фактически в этом случае подпрограмме передается адрес переменной). Изменение параметра переменной приводит к изменению самого фактического параметра в вызывающей подпрограмме.
В случае если параметр определен как параметр-константа, в подпрограмму также передается адрес области памяти, в которой располагается переменная или вычисленное значение. Однако компилятор блокирует любые присваивания параметру-константе нового значения в теле подпрограммы.
Пример:
Program DemoConst;
Сonst
a: integer=5;
b: integer =7;
procedure Inc2 (Var c: integer; b: integer);
Begin
c: = c+c;
b: = b+b;
writeln ('удвоенные:', с:5, b:5)
End;
Begin
writeln ('исходные:', а:5, b:5);
Inc2 (a,b);
writeln ('результат:', a:5, b;5)
End.
В результате выполнения программы будет выведено:
исходные: 5 7
удвоенные: 10 14
результат; 10 7
Поясним программу. В ней задаются два целых числа 5 и 7. Эти числа передаются процедуре Inc2, в которой они удваиваются. Один из параметров передается как параметр-переменная, другой - как параметр-значение. Значения параметров до и после вызова процедуры, а также результат их удвоения выводятся на экран. Удвоение второго формального параметра в процедуре Inc2 не вызвало изменения фактической переменной В, поскольку он описан в заголовке процедуры как параметр-значение. Этот пример может служить еще и иллюстрацией механизма «закрывания» глобальной переменной одноименной локальной. Переменная В объявлена как глобальная, в теле процедуры ее «закрыла» локальная переменная В, объявлена как параметр-значение.
Основные понятия структурного программирования
Фактически подпрограммы представляют собой инструмент, с помощью которого любая программа может быть разбита на ряд, в известной степени, независимых друг от друга частей. Такое разбиение бывает необходимо по двум причинам:
Во-первых, это средство экономии памяти; каждая подпрограмма существует в программе в единственном экземпляре, в то время как обращаться к ней можно многократно из разных точек программы. При вызове подпрограммы активизируется последовательность образующих его операторов, а с помощью передаваемых подпрограмме параметров нужным образом модифицируется реализуемый в ней алгоритм.
Вторая причина заключается в применении методики нисходящего проектирования программ. В этом случае алгоритм представляется в виде последовательности относительно крупных подпрограмм, реализующих более или менее самостоятельные смысловые части алгоритма. Подпрограммы, в свою очередь, могут разбиваться на менее крупные подпрограммы нижнего уровня и т.д. последовательное структурирование программы продолжается до тех пор, пока реализуемые подпрограммами алгоритмы не станут настолько простыми, чтобы их можно было легко запрограммировать.
Как известно, любое имя в программе должно быть обязательно описано, перед тем как оно появится среди исполняемых операторов. Не делается исключения и в отношении подпрограмм: каждую свою процедуру и функцию программисту необходимо описать в разделе описаний.
Программа | ||||||
Подпрограмма А | ||||||
Подпрограмма AI | ||||||
Подпрограмма А2 | ||||||
Подпрограмма В | ||||||
Подпрограмма В1 | ||||||
П | Подпрограмма В2 | |||||
Подпрограмма В21 | ||||||
Подпрограмма В22 | ||||||
Пример структуры программы
Описать подпрограмму – это значит указать ее заголовок и тело. В заголовке объявляются имя подпрограммы и формальные параметры, если они есть. Для функции, кроме того, указывается тип возвращаемого ею результата. За заголовком следует тело подпрограммы, которое, подобно программе состоит из раздела описаний и раздела исполняемых операторов. В разделе описаний подпрограммы могут встретиться описания подпрограмм низшего уровня, в тех - описания других подпрограмм и т.д.
Иерархия описаний для программы, структура которой показана выше, имеет вид:
Program...;
Procedure A;
Procedure Al;
Begin
……..
End {Al};
Procedure A2:
Begin
………
End {A2};
Begin {A}
………
End {A},
Procedure В;
Procedure ВI
Begin
…….
End;{Bl};
Procedure B2;
Procedure B21,
и т.д.
Подпрограмма любого уровня имеет обычно множество имен констант, переменных, типов и вложенных в нее подпрограмм низшего уровня. Считается, что все имена, описанные внутри подпрограммы, локадизуются в ней, т.е. они как бы невидимы снаружи подпрограммы. Таким образом, со стороны операторов, использующих обращение к подпрограмме, она трактуется как «черный ящик», в котором реализуется тот или иной алгоритм. Все детали этой реализации скрыты от глаз пользователя подпрограммы, и поэтому недоступны ему. Так, в рассмотренном выше примере из основной программы можно обратиться к процедурам А и В, но нельзя вызвать ни одну из вложенных в них процедур А1, А2, В1 и т.д.
Это относится не только к именам подпрограмм, но и вообще к любым именам (идентификаторам), объявленным в них константам, переменным, меткам и т.д. все имена (идентификаторы) в пределах подпрограммы должны быть уникальными и не могут совпадать с именем самой подпрограммы.
При входе в подпрограмму низшего уровня становятся доступными не только объявленные в ней имена, но и сохраняется доступ ко всем именам верхнего уровня. Образно говоря, любая подпрограмма как бы окружена полупрозрачными стенками; снаружи подпрограммы мы не видим ее внутренности, но, попав в подпрограмму, можем наблюдать все, что делается снаружи. Так, например, из подпрограммы В21 мы можем вызвать подпрограмму А, использовать имена, объявленные в основной программе, в подпрограммах В и В2. И даже обратиться к ним. Любая подпрограмма может, наконец, вызвать саму себя - такой способ вызова называется рекурсией.
Пусть имеем такое написание:
Program..,;
VarVl:....;
Procedure A;
VarV2:..,;
Procedure В;
VarV3...;
Procedure В1;
VarV4:...;
Procedure B11;
VarV5;
Из процедуры В11 доступны все пять переменных VI,... V5, из процедуры В1 доступны переменные VI,... V4, из центральной программы -только VI.
При взаимодействии подпрограмм одного уровня иерархии вступает в силу основное правило Турбо Паскаль: любая подпрограмма перед ее использованием должны быть описана. Поэтому из подпрограммы В можно вызвать подпрограмму А, но из А вызвать В невозможно. Подпрограмме доступны только те объекты верхнего уровня, которые описаны до описания данной программы. Эти объекты называются глобальными по отношению к подпрограмме.
В отличие от стандартного Паскаля, в Турбо Паскаль допускается произвольная последовательность описания констант, переменных, типов, меток и подпрограмм. Например, раздел Var описания переменных может появляться в пределах раздела описаний одной и той же подпрограммы много раз и перемежаться с объявлениями других объектов и подпрограмм. Для Турбо Паскаль безразличен порядок следования и количество разделов Var, Const, Type, Label, но при определении области действия этих описаний следует помнить, что имена (идентификаторы), описанные ниже по тексту программы, недоступны из ранее описанных подпрограмм, например:
Var VI:...;
Procedure S;
VarV2:...;
End{S};
VarV3:...;
Из процедуры S можно обратиться к переменным VI и V2, но нельзя использовать V3, поскольку описание V3 следует в программе за описанием процедуры S.
Локальные имена (идентификаторы) в подпрограмме могут совпадать с ранее объявленными глобальными именами. В этом случае считается, что локальное имя как бы закрывает глобальное и делает его недоступным, например:
Var i: integer;
Procedure P;
Var
i: integer;
Begin
Writeln (i)
End{P};
Begin
I:=1;
P;
End.
Эта программа выведет на экран произвольное значение внутренней переменной. Если убрать описание переменной из процедуры Р, то на экран будет выведено значение глобальной переменной I, т.е. 1.
Таким образом, одноименные глобальные и локальные переменные – это разные переменные. Любое обращение к таким переменным в теле подпрограммы трактуется как обращение к локальным переменным, т.е. глобальные переменные в этом случае попросту недоступны.
Пример процедуры, работающей со строками.
При использовании функции Up Case программист, не владеющий анпийским языком, сталкивается с существенными ограничениями сферы применения своих программ. Возникает необходимость в построении функции, преобразующей строчные литеры русского алфавита в прописные. Program MyFunctionUpCase;
Uses CRT;
Var
Words: string;
Procedure MyUpCase (Var Words: string);
(Данная программа обеспечивает полное преобразование строчных литер в прописные, включая литеры русского алфавита}
Var
i: BYTE
Procedure StringManipulation(Var Words: String; i: BYTE);
(Данная процедура осуществляет посимвольное преобразование строки}
Begin
Words [i] of
'a':Words[i]: = 'A';
'6':Words[i]: = 'E';
'в': Words [i]: = 'B';
……………
end;
End;
Begin
for i: = 1 to Length(Words) do StringManipulation(Words, i);
CirScr;
Words: = ‘Современная гуманитарная академия’;
MyUpcase(Words);
Writeln(Words);
End.
В процедуре MyUpcase объявляется только одна переменная. Это переменная типа BYTE, предназначенная в качестве счетчика. Для переменной i был выбран тип BYTE, поскольку максимальная длина строки равна 255 символов, а переменная BYTE как раз обеспечивает хранение чисел с величиной до 255.
В процедуре StringMampulation сначала производится попытка преобразования символов с помощью функции UpCase. Затем для символов русского алфавита, не преобразуемых этой функцией, реализуется прямое преобразование с помощью конструкции CASE OF.
Использование структурного программирования позволяет создавать более сложные, динамичные программные проекты. Пример программы, которая создает на экране окно и имитирует движение в нем кубика белого цвета, который при столкновении с гранью окна отскакивает от него по закону отражения.
Program DemoProcedures;
Uses CRT;
Procedure dvigenie;
Var a,b,x,y:integer;
ch:char;
Procedure Okno;
begin
TextBackGround(blue);
Window(10,1,60,15);
Clrscr;
end;
Procedure Kubik;
begin
TextBackGround(white);
Window(x,y,x+1,y);
ClrScr;
end;
Procedure Dvig;
begin
repeat
Okno;
x:=x+a;
y:=y+b;
kubik;
delay(2000);
until (x>=59) or (x<=10) or (y<=1) or (y>=15);
end;
begin
x:=10;
y:=1;
a:=1;
b:=1;
repeat
if keypressed
then ch:=readkey;
dvig;
if (x<=10) and ((a=-1) and (b=1)) then a:=1;
if (x<=10) and ((a=-1) and (b=-1)) then a:=1;
if (y>=15) and ((a=1) and (b=1)) then b:=-1;
if (y>=15) and ((a=-1) and (b=1)) then b:=-1;
if (x>=59) and ((a=1) and (b=1)) then a:=-1;
if (x>=59) and ((a=1) and (b=-1)) then a:=-1;
if (y<=1) and ((a=1) and (b=-1)) then b:=1;
if (y<=1) and ((a=-1) and (b=-1)) then b:=1;
until ch=#32;
end;
Begin
TextBackGround(0);
ClrScr;
dvigenie;
End.
Задния
Создать программу, имитирующую на экране стакан с чаем, в который падает кусочек сахара. Пока сахар тонет, он тает. Около нижней грани он исчезает.
Создать программу, имитирующую движение в окне надписи, при столкновении с гранью окна, она отскакивает по закону отражения.
Создать программу, имитирующую тараканьи бега. При запуске программы по экрану начинают двигаться пять кубиков слева направо:
а) кубики движутся с разными скоростями, которые устанавливаются в момент запуска программы;
б) скорость кубиков меняется периодически во время движения;
в) скорость кубиков меняется случайным образом у кубиков произвольно во время движения.
Создать программу, имитирующую попарное мигание двух кубиков в разных частях экрана.
Литература
Абрамов С.А., Зима Е.В. Начала информатики. - М.: Наука, 1989.
Алексеев В.Е., Ваулие А.С., Петрова Г.Б. Вычислительная техника и программирование. Практикум по программированию: Практическое пособие / Под ред. А.В. Петрова. М.: Высшая школа, 1991.
Вострокнутов И.Е. Турбо Паскаль. Теория, примеры, задания. Часть 1. Ядро. Арзамас. АГПИ 2000.
Гуденко Д., Петроченко Д. Сборник задач по программированию. СПб.: Питер, 2003.
Жидкова О.А., Кудрявцева Е.К. Алгоритмы и основы программирования. М.: Интеллект-Центр, 1999.
Жидкова О.А., Кудрявцева Е.К. Справочные материалы для программирования на языке Паскаль. М.: Интеллект-Центр, 2001
Жилин С.А., Жилина Н.Б. Информатика: Теория и практика решения задач. М.: РКНК, 2001.
Зеленяк О.П. Практикум программирования на Turbo Pascal: Задачи, алгоритмы и решения. К.: Диа Софт, 2001.
Культин Н.Б. Turbo Pascal в задачах и примерах. СПб.: БХВ – Петербург, 2000.
Культин Н. С/С++ в задачах и примерах. - СПб.: БХВ - Петербург, 2001.
Марченко А.И. Марченко А.А. Программирование в среде Турбо Паскаль 7.0. - М.: Бином Универсал, К.: ЮНИОР, 1997.
Милов А.В. Основы программирования в задачах и примерах: Учебный курс. Харьков: Фолио, 2002.
Семашко Г.А., Салтыков А.И. Программирование на языке Паскаль. М.: Наука, 1988.
Фаронов В.В. Турбо Паскаль 7.0. Начальный курс. Учебное пособие. - М.: Нолидж, 1997.
Федоренко А. Алгоритмы и программы на Turbo Pascal: Учебный курс. СПб.: Питер, 2001.
Дата публикования: 2015-06-12; Прочитано: 242 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!